Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC DropDownListFor - Must I manually re-populate the options after validation fail?

I have a viewmodel class which contains a couple of properties. Basically, the current record (which the user is editing) and a list of options (which is used to populate a dropdown list using DropDownListFor).

After the form is submitted, if the modelstate is not valid 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 about the list of values for the dropdown list.

If I do nothing, on the validation fail and return to the page I get an 'object reference not set to instance of an object' error because the list property of the viewmodel is null. I know that it's null because it wasn't bound from the form post, so I can repopulate it from the database before returning to the view.

Is that the correct way to go about it, or am I missing a more obvious way of making the dropdown values persist?

like image 259
Gavin Avatar asked Nov 14 '10 16:11

Gavin


People also ask

How does MVC validation work?

Validation is an important aspect in ASP.NET MVC applications. It is used to check whether the user input is valid. ASP.NET MVC provides a set of validation that is easy-to-use and at the same time, it is also a powerful way to check for errors and, if necessary, display messages to the user.

How do I populate a DropDownList based on another dropdown selected value?

You will have to simply execute the script named CreateCascadingDatabase. sql stored in the SQL Folder of the attached sample and it will create the complete database with data. Below is the HTML Markup which contains three ASP.Net DropDownList controls each for Country, State and City.


1 Answers

Yes, that's the correct way if you intend to return the same view in the POST action:

  1. bind the list in the GET action from database
  2. render the view
  3. the user submits the form to the POST action
  4. in the this action you fetch only the selected value so if the model is invalid and you need to redisplay the view you need to get the list back from the database in order to populate your view model.

Here's 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");
    }
}
like image 96
Darin Dimitrov Avatar answered Oct 02 '22 08:10

Darin Dimitrov