这与先前的问题有关从数据库绑定下拉列表有关.下拉列表被绑定并填充,但是抛出未设置为对象实例的对象引用".提交表单时浏览器出现错误.
This is related to an earlier question on binding a dropdownlist from a database. The dropdownlist is being bound and populated but is throwing an "Object reference not set to an instance of an object" error in the browser when submitting the form.
调试时,我在m =>上添加了一个快速监视.Html.DropDownListFor(...)帮助程序方法的m.SelectedDepartment参数,并得到:因为它不是委托类型,所以无法将lambda表达式转换为类型'object'".
When debugging, I added a quick watch on the m => m.SelectedDepartment parameter of the Html.DropDownListFor(...) helper method and got: "Cannot convert lambda expression to type 'object' because it is not a delegate type".
查看:
@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; }更新
现在正在工作.更新/添加了以下代码,以便在回发后显示包含所选部门值的成功消息来重新呈现表单.
It's working now. The following code was updated/added to get the form re-rendering after a postback with a success message containing the value of the selected department.
查看:
@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"); } }存储库-处理POST的新的重载方法
Repository - New overloaded method to handle 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.请执行以下操作.
Modify the controller to have a new api that supports a POST call. Do as follows.
向此方法添加一个get方法,该方法将在加载视图时被调用,如下所示:
Add this method a get method that is called when the view is loaded, like this:
[HttpGet] public ActionResult GetBudgetsActuals() { repo = new BudgetDemoRepository(); ModelState.Clear(); try { return View(repo.GetBudgetsActuals()); } catch { return View("Error"); } }添加在提交表单时调用的post方法:
Add a post method that is called when the form is submitted:
[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 方法,如下所示:
If you are getting an issue with the overload of DropDownListFor method, then you can also try DropDownList method like below:
@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"); } }更多推荐
从强类型视图回发DropDownList
发布评论