Pismotality
Pismotality

Reputation: 2289

DropDownListFor value cannot be null

I am new to MVC. I am using a DropDownListFor to populate a number of Customer fields when a Company is selected. I am using the following code for the DropDownListFor:

 @Html.DropDownListFor(model => model.CustomerId, new SelectList(ViewBag.Customers, "CustomerId", "Company"), "---Select one---", new { htmlAttributes = new { @class = "company" } });
 @Html.HiddenFor(model => model.Company)

This code retrieves the Customer data:

[HttpPost]
public ActionResult GetCustomer(int custId)
{
    var data = db.Customers.Find(custId);
    return Json(data);
}

The relevant fields in the ViewModel (from the Customer table) are:

public int CustomerId { get; set; }
public string Company { get; set; }

The code in the Create method that creates the ViewBag:

public ActionResult Create()
{
    QuoteViewModel qvm = new QuoteViewModel();
    qvm.QuoteDetail = new List<QuoteDetail>(); 
    var customers = db.Customers.ToList();
    ViewBag.Customers = customers;
    return View(qvm);
}

And here is the code for the POST:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(QuoteViewModel qvm)
{
    if (ModelState.IsValid)
    {
        Quote quote1 = new Quote();
        quote1.CustomerId = qvm.CustomerId;
        ...
        db.Quotes.Add(quote1);
        customer.CustomerId = qvm.CustomerId;
        ...
        db.Entry(customer).State = EntityState.Modified;
        bool saveFailed;
        do
        {
            saveFailed = false;
            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                saveFailed = true;
                var objContext = ((IObjectContextAdapter)db).ObjectContext;
                // Get failed entry
                var entry = ex.Entries.Single();
                // Now call refresh on ObjectContext
                objContext.Refresh(RefreshMode.ClientWins, entry.Entity);
            }
        } while (saveFailed);
        return RedirectToAction("Index");
    }
    return View(qvm);
}

The population of the fields works fine, but when I attempt to Create the view model I get an error "Value cannot be null" on the DropDownListFor. I have researched others having this issue but cannot find an answer that applies to this case. Any help would be much appreciated.

Upvotes: 1

Views: 1619

Answers (2)

user3559349
user3559349

Reputation:

The error is because in the POST method you return the view (ModelState is invalid), but have not set the value of ViewBag.Customers as you did in the GET method, so it null and you cannot create a SelectList from a null collection.

Your need assign ViewBag.Customers as you did in the GET method before your return View(qvm); statement.

As a side note, since you using a view model, that view model should contain a property (say) public IEnumerable<SelectListItem> CustomerList { get; set; } and you set that in the controller methods, and in the view

@Html.DropDownListFor(model => model.CustomerId, Model.CustomerList, "---Select one---", new { @class = "company" });

Upvotes: 2

m.lucas
m.lucas

Reputation: 351

Are you making a full page POST request when a Company is selected? If you are, you need to fill ViewBag.Customers because of ViewBag's lifetime.

http://www.dotnettricks.com/learn/mvc/viewdata-vs-viewbag-vs-tempdata-vs-session

Upvotes: 1

Related Questions