How to use dropdownlists in ASP.NET MVC with lookup values without ViewBag?

1.3k views Asked by At

This should be really easy, and I can't for the life of me realize what I haven't found any answers to this despite at least an hour of Googling. Anyway, here we go:

I want to create a simple ASP.NET MVC view with some dropdowns that allow the user to select some values, that are then saved as ID:s to the database. As I've been told that ViewBag/ViewData is the devils work I've tried to solve this by adding a selectlist to my (View)Model like:

public virtual SelectList Accommodations { get; set; }

and then in my controller fill it up with something like:

LoanApplication theLoanApplication = new LoanApplication();
            theLoanApplication.Accommodations = new SelectList(db.Accommodations.ToList(), "AccommodationID", "Name");

and finally in my view use this to get it all working:

@Html.DropDownListFor(model => model.AccommodationID, Model.Accommodations, "Choose Accommodation")

This works as it should, but when i try to save the model, I get errors that the Accommodations property (the list) is null which is kind of expected. Everything else in my model is as it should though.

I've looked at the well known "Countoso University" code example on the ASP.NET site and in it they seem to use ViewBag to solve similar problems. Is it so that ViewBag isn't all that bad to use in a scenario like that and that it might even be the best possible solution? If not, what would the prefered way be to solve this problem and not use ViewBag/ViewData?

Thank you.

1

There are 1 answers

2
fdomn-m On

In your controller post action, simply reload the Accommodations list from the db as you do in the get action.

You'd normally do this if the modelstate has errors and you want to pass these back to the view, otherwise there's no need to reload the select list. You've not specified exactly where it gives null reference, so I'm assuming when you have modelstate errors and reloading the view to show the server-side errors. eg:

[HttpPost]
public ActionResult EditAccommodation(AccommodationViewModel model)
{
    if (!ModelState.IsValid) 
    {
        model.Accommodations = new SelectList(db.Accommodations.ToList(), "AccommodationID", "Name");
        return View(model);
    }

    // else modelstate ok and model.AccommodationID set 
    ...
}

As an aside, I recommend you keep the variable names clear, eg:

public virtual SelectList AccommodationSelectList { get; set; }

then, when you refer to Accommodations it's clear if it's the select list (which isn't really a list of accommodations, it's a list of select items) or the real list of accommodations from the database.