Yes, you need to repopulate it. Only the selected value of a dropdown list is sent via a form. It's perfectly normal to do this. In general, if you have data available on the server, it always makes sense to cache it/query for it again, rather than trusting any input from a user.
To conveniently build SelectList
s, rather than using SelectListItem
, I use a method on a base controller:
[NonAction]
public SelectList BuildSelectList<TSource>(IEnumerable<TSource> source,
Expression<Func<TSource, int>> valueKey, Expression<Func<TSource, string>> textKey,
object selectedValue = null)
{
var selectedValueKey = ((MemberExpression)(MemberExpression)valueKey.Body).Member.Name;
var selectedTextKey = ((MemberExpression)(MemberExpression)textKey.Body).Member.Name;
return new SelectList(source, selectedValueKey, selectedTextKey, selectedValue);
}
Note the use of NonActionAttribute, which is used to indicate that a public controller method is not an action method.
Then in the controller, it's easy to build any list again, without polluting the actions too much. For example:
[HttpPost]
public ActionResult Index(SomeViewModel model)
{
if (ModelState.IsValid)
return RedirectToAction("Success");
// The model wasn't valid, so repopulate the dropdown
model.People = BuildSelectList(db.People, m => m.Id,
m => m.Name, model.PersonId);
return View(model);
}
You could do something similar for SelectListItem
, rather than manually rebuilding your lists each time.