MVC DropDownListFor. Do I have to manually re-populate the parameters after validation is complete?

I have a viewmodel class that contains a couple of properties. Basically, the current record (which the user edits) and the parameter list (which is used to populate the drop-down list using DropDownListFor).

After submitting the form, if the state of the model is invalid, I return to the view. I understand that the form is populated using the β€œrejected” input from ModelState["name"].Value.AttemptedValue , but I'm not sure what to do with the list of values ​​for the drop-down list.

If I do nothing, when checking fails and returning to the page, I get the error "link to an object not installed in the object instance", because the list property for viewmodel is null. I know that it is null because it was not associated with the form post, so I can re-populate it from the database before returning to the view.

Is this the right way to get around this, or am I skipping the more obvious way to make the dropdown values ​​persist?

+7
asp.net-mvc-2
source share
2 answers

Yes, this is the right way if you intend to return the same view in a POST action:

  • bind list in GET action from database
  • display view
  • user submits form to POST action
  • in this step, you select only the selected value, so if the model is invalid and you need to redisplay the view needed to return the list from the database to populate your view model.

Here is an example of a commonly used pattern in MVC:

 public class HomeController : Controller { public ActionResult Index() { var model = new MyViewModel { Items = _repository.GetItems() }; return View(model); } [HttpPost] public ActionResult Index(MyViewModel model) { if (!ModelState.IsValid) { // Validation failed, fetch the list from the database // and redisplay the form model.Items = _repository.GetItems(); return View(model); } // at this stage the model is valid => // use the selected value from the dropdown _repository.DoSomething(model.SelectedValue); // You no longer need to fetch the list because // we are redirecting here return RedirectToAction("Success", "SomeOtherController"); } } 
+10
source share

You can use the xhr ajax call to submit your data instead of submitting the default form. Submit button.

The advantage of this method is that you will not need to re-populate the lists.

On the client side and after the ajax callback, you can decide what you need by checking the status value

 $.ajax({ url: '@Url.Action("Index", "Controller")', data: $("#form").serialize(), type: 'POST', success: function (data) { if (data.status == "Successful") { // you can redirect to another page by window.location.replace('New URL') } else { // you can display validation message } } }); 

You ActionMethod will look like this:

 [HttpPost] public JsonResult Index() { if (ModelState.IsValid) { return Json(new { status = "Success" }); } else { return Json(new { status = "Fail" }); } } 
0
source share

All Articles