从强类型视图回发 DropDownList
Posting Back DropDownList from Strongly Typed View
这与从数据库绑定下拉列表的 有关。下拉列表正在绑定和填充,但在提交表单时在浏览器中抛出“未设置对象实例的对象引用”错误。
调试时,我在 Html.DropDownListFor(...) 辅助方法的 m => m.SelectedDepartment 参数上添加了一个快速观察并得到:“无法将 lambda 表达式转换为类型 'object' 因为它不是委托类型。
查看:
@model BudgetDemo.Models.BudgetsActualsViewModel
@using (Html.BeginForm("GetBudgetsActuals", "BudgetsActuals", FormMethod.Post))
{
@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments,
"Select Department", new { @class = "form-control" })
}
ViewModel:
public class BudgetsActualsViewModel
{
[Display(Name = "Cost Center/Department")]
[Required(ErrorMessage = "Cost Center/Department is required.")]
[StringLength(62)]
public string SelectedDepartment { get; set; }
public List<SelectListItem> Departments { get; set; }
}
控制器:
// GET: Render view with dropdowns
public ActionResult GetBudgetsActuals()
{
repo = new BudgetDemoRepository();
ModelState.Clear();
try
{
return View(repo.GetBudgetsActuals());
}
catch
{
return View("Error");
}
}
存储库:
public BudgetsActualsViewModel GetBudgetsActuals()
{
...
BudgetsActualsViewModel budgetsActuals = new BudgetsActualsViewModel()
{ Departments = new List<SelectListItem>() };
// Query returning correct data from DB here
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
budgetsActuals.Departments.Add(
new SelectListItem
{
Text = ds.Tables[0].Rows[i]["Department"].ToString(),
Value = ds.Tables[0].Rows[i]["ListValue"].ToString()
}
);
}
return budgetsActuals;
}
更新
现在可以了。以下代码 updated/added 用于在回发后重新呈现表单,其中包含包含所选部门值的成功消息。
查看:
@model BudgetDemo.Models.BudgetsActualsViewModel
@Html.AntiForgeryToken()
@using (Html.BeginForm("GetBudgetsActuals", "BudgetsActuals",
FormMethod.Post))
{
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@if (TempData["SuccessMessage"] != null)
{
<p class="alert alert-success"
id="successMessage">@TempData["SuccessMessage"]</p>
}
@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments,
"Select Department", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.SelectedDepartment, "",
new { @class = "text-danger" })
}
控制器:
// GET
public ActionResult GetBudgetsActuals()
{
Populate Department dropdown from DB and Year dropdown (static) here
repo = new BudgetDemoRepository();
//ModelState.Clear();
try
{
return View(repo.GetBudgetsActuals());
}
catch
{
return View("Error");
}
}
// POST
[HttpPost]
public ActionResult GetBudgetsActuals(BudgetsActualsViewModel model)
{
try
{
repo = new BudgetDemoRepository();
if (ModelState.IsValid)
{
TempData["SuccessMessage"] = "Value of SelectedDepartment is: "
+ model.SelectedDepartment;
return View(repo.GetBudgetsActuals(model));
}
else
{
model.Departments = repo.GetBudgetsActuals().Departments;
return View(model);
}
}
catch
{
return View("Error");
}
}
Repository - 处理 POST
的新重载方法
public BudgetsActualsViewModel GetBudgetsActuals(BudgetsActualsViewModel model)
{
....
// Get the data again
....
budgetsActuals.SelectedDepartment = model.SelectedDepartment;
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
budgetsActuals.Departments.Add(
new SelectListItem
{
Text = ds.Tables[0].Rows[i]["Department"].ToString(),
Value = ds.Tables[0].Rows[i]["ListValue"].ToString()
}
);
}
return budgetsActuals;
}
修改 controller
以获得支持 POST
调用的新 api。如下操作。
将此方法添加到加载视图时调用的 get 方法,如下所示:
[HttpGet]
public ActionResult GetBudgetsActuals()
{
repo = new BudgetDemoRepository();
ModelState.Clear();
try
{
return View(repo.GetBudgetsActuals());
}
catch
{
return View("Error");
}
}
添加一个 post 提交表单时调用的方法:
[HttpPost] // Decorate with this attribute
public ActionResult PostBudgetsActuals(BudgetDemo.Models.BudgetsActualsViewModel model)
{
var selectedDepartment = model.SelectedDepartment;
// dostuff with the model
return somethingFromHere;
}
并像这样更改视图:
@model BudgetDemo.Models.BudgetsActualsViewModel
@using (Html.BeginForm("PostBudgetsActuals", "BudgetsActuals", FormMethod.Post))
{
@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments,
"Select Department", new { @class = "form-control" })
}
如果您遇到 DropDownListFor
方法重载的问题,那么您也可以尝试如下 DropDownList
方法:
@using (Html.BeginForm("PostBudgetsActuals", "BudgetsActuals", FormMethod.Post))
{
@Html.DropDownList("SelectedDepartment", Model.Departments,
"Select Department", new { @class = "form-control" })
}
更新
// POST
[HttpPost]
public ActionResult GetBudgetsActuals(BudgetsActualsViewModel model)
{
try
{
repo = new BudgetDemoRepository();
if (model.SelectedDepartment != null)
{
TempData["SuccessMessage"] = "Value of SelectedDepartment is:
" + model.SelectedDepartment;
}
model.Departments = repo.GetBudgetsActuals().Departments;
return View(model);
}
catch
{
return View("Error");
}
}
这与从数据库绑定下拉列表的
调试时,我在 Html.DropDownListFor(...) 辅助方法的 m => m.SelectedDepartment 参数上添加了一个快速观察并得到:“无法将 lambda 表达式转换为类型 'object' 因为它不是委托类型。
查看:
@model BudgetDemo.Models.BudgetsActualsViewModel
@using (Html.BeginForm("GetBudgetsActuals", "BudgetsActuals", FormMethod.Post))
{
@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments,
"Select Department", new { @class = "form-control" })
}
ViewModel:
public class BudgetsActualsViewModel
{
[Display(Name = "Cost Center/Department")]
[Required(ErrorMessage = "Cost Center/Department is required.")]
[StringLength(62)]
public string SelectedDepartment { get; set; }
public List<SelectListItem> Departments { get; set; }
}
控制器:
// GET: Render view with dropdowns
public ActionResult GetBudgetsActuals()
{
repo = new BudgetDemoRepository();
ModelState.Clear();
try
{
return View(repo.GetBudgetsActuals());
}
catch
{
return View("Error");
}
}
存储库:
public BudgetsActualsViewModel GetBudgetsActuals()
{
...
BudgetsActualsViewModel budgetsActuals = new BudgetsActualsViewModel()
{ Departments = new List<SelectListItem>() };
// Query returning correct data from DB here
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
budgetsActuals.Departments.Add(
new SelectListItem
{
Text = ds.Tables[0].Rows[i]["Department"].ToString(),
Value = ds.Tables[0].Rows[i]["ListValue"].ToString()
}
);
}
return budgetsActuals;
}
更新
现在可以了。以下代码 updated/added 用于在回发后重新呈现表单,其中包含包含所选部门值的成功消息。
查看:
@model BudgetDemo.Models.BudgetsActualsViewModel
@Html.AntiForgeryToken()
@using (Html.BeginForm("GetBudgetsActuals", "BudgetsActuals",
FormMethod.Post))
{
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@if (TempData["SuccessMessage"] != null)
{
<p class="alert alert-success"
id="successMessage">@TempData["SuccessMessage"]</p>
}
@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments,
"Select Department", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.SelectedDepartment, "",
new { @class = "text-danger" })
}
控制器:
// GET
public ActionResult GetBudgetsActuals()
{
Populate Department dropdown from DB and Year dropdown (static) here
repo = new BudgetDemoRepository();
//ModelState.Clear();
try
{
return View(repo.GetBudgetsActuals());
}
catch
{
return View("Error");
}
}
// POST
[HttpPost]
public ActionResult GetBudgetsActuals(BudgetsActualsViewModel model)
{
try
{
repo = new BudgetDemoRepository();
if (ModelState.IsValid)
{
TempData["SuccessMessage"] = "Value of SelectedDepartment is: "
+ model.SelectedDepartment;
return View(repo.GetBudgetsActuals(model));
}
else
{
model.Departments = repo.GetBudgetsActuals().Departments;
return View(model);
}
}
catch
{
return View("Error");
}
}
Repository - 处理 POST
的新重载方法public BudgetsActualsViewModel GetBudgetsActuals(BudgetsActualsViewModel model)
{
....
// Get the data again
....
budgetsActuals.SelectedDepartment = model.SelectedDepartment;
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
budgetsActuals.Departments.Add(
new SelectListItem
{
Text = ds.Tables[0].Rows[i]["Department"].ToString(),
Value = ds.Tables[0].Rows[i]["ListValue"].ToString()
}
);
}
return budgetsActuals;
}
修改 controller
以获得支持 POST
调用的新 api。如下操作。
将此方法添加到加载视图时调用的 get 方法,如下所示:
[HttpGet]
public ActionResult GetBudgetsActuals()
{
repo = new BudgetDemoRepository();
ModelState.Clear();
try
{
return View(repo.GetBudgetsActuals());
}
catch
{
return View("Error");
}
}
添加一个 post 提交表单时调用的方法:
[HttpPost] // Decorate with this attribute
public ActionResult PostBudgetsActuals(BudgetDemo.Models.BudgetsActualsViewModel model)
{
var selectedDepartment = model.SelectedDepartment;
// dostuff with the model
return somethingFromHere;
}
并像这样更改视图:
@model BudgetDemo.Models.BudgetsActualsViewModel
@using (Html.BeginForm("PostBudgetsActuals", "BudgetsActuals", FormMethod.Post))
{
@Html.DropDownListFor(m => m.SelectedDepartment, Model.Departments,
"Select Department", new { @class = "form-control" })
}
如果您遇到 DropDownListFor
方法重载的问题,那么您也可以尝试如下 DropDownList
方法:
@using (Html.BeginForm("PostBudgetsActuals", "BudgetsActuals", FormMethod.Post))
{
@Html.DropDownList("SelectedDepartment", Model.Departments,
"Select Department", new { @class = "form-control" })
}
更新
// POST
[HttpPost]
public ActionResult GetBudgetsActuals(BudgetsActualsViewModel model)
{
try
{
repo = new BudgetDemoRepository();
if (model.SelectedDepartment != null)
{
TempData["SuccessMessage"] = "Value of SelectedDepartment is:
" + model.SelectedDepartment;
}
model.Departments = repo.GetBudgetsActuals().Departments;
return View(model);
}
catch
{
return View("Error");
}
}