Jeahel
Jeahel

Reputation: 1143

DropDownListFor not directly connected to model

I am having difficulties using the DropDownListFor helper in a form I want to use for login (security is not the matter here). I would like, instead of asking for the user to type its username, to let him select it from a dropdown list.

But I can't manage to make ASP.NET automatically set the EmpName propoerty of my model to the selected value in the dropdown list.

This is what I've done tried:

The following method displays the login page

[HttpGet]
public ActionResult Index()
{
   // Retrieving all users from DB
   using (var db = new BidManagementContext())
   {
       var users = from u in db.LOGIN
                   select u.EmpName;

       ViewBag.AllUsers = new SelectList(users.ToList());
       return View();
   }
}

And these are some lines from the view:

<div class="form-group">
   @Html.LabelFor(model => model.EmpName, htmlAttributes: new { @class = "control-label col-md-2" })
   <div class="col-md-10">
       @Html.DropDownListFor(model => model.EmpName, ViewBag.AllUsers as SelectList, new { @class = "form-control" })
   </div>
</div>

With how I did things, I have an error when ASP.NET tries to bind the dropdown selected value to the model:

An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code

Additional information: There is no ViewData item of type 'IEnumerable' that has the key 'EmpName'.

I'm not sure what to do here :-/

Upvotes: 1

Views: 68

Answers (1)

user3559349
user3559349

Reputation:

The error message means that the value of ViewBag.AllUsers is null. This is possibly because your returning the view after a submit but not reassigning the SelectList. I recommend refactoring the code for populating SelectLists to a private method that can be called in both the GET and POST methods if your return the view.

Edit (example added)

HttpGet]
public ActionResult Index()
{
  YourViewModel model = new YourViewModel();
  ConfigureViewModel(model);
  return View(model);
}

[HtppPost]
public ActionResult Index(YourViewModel model)
{
  if (!ModelState.IsValid)
  {
    ConfigureViewModel(model);
    return View(model);
  }
  // Save and redirect
}

private void ConfigureViewModel(YourViewModel model)
{
  using (var db = new BidManagementContext())
  {
    var users = from u in db.LOGIN select u.EmpName;
    ViewBag.AllUsers = new SelectList(users.ToList());
    // or better, model.AllUsers = new SelectList(users.ToList());
  }
  // any other common operations
}

Upvotes: 2

Related Questions