I have created a viewmodel
public VMPosition
{
public VMPosition(){}//for model binder
public VMPosition(int EmployeeID)
{
PositionStatusList = new SelectList(_repo.getStatuses);
//populate other properties
}
public int CurrentPositionID { get; set; }
public int EmployeeID { get; set; }
public int CurrentPositionHistoryID { get; set; }
public bool AddingNew { get; set; }
public bool ClosingCurrent { get; set; }
public string CurrentPosition { get; set; }
public DateTime CurrentPositionStartDate { get; set; }
public string ReasonForDeparture { get; set; }
public SelectList PositionStatusList { get; set; }
}
My GET ActionResult is defined as
public ActionResult UpdatePosition(int id)
{
return View(new VMPosition(id));
}
My POST actionresult is defined as
public ActionResult UpdatePosition(int id, VMPosition Position)
{
if(ModelState.IsValid){
Position Current = new Position{Position.Title etc..}
//save to db
return redirectToAction("someAction");
}
return View(Position);//here is the problem
}
My SelectList is populated in a constructor that accepts one parameter. Modelbinder cannot and should not call the constructor if the modelstate is invalid. I will have to return the View with model object (which in this case don’t contain SelectList value). How can handle this scenario when using view Models.
I can manually populate these values in actionresult but that will violate the DRY principle. However, for the purposes of this question, I’d like help addressing the bigger design question.
When dealing with dropdowns in my viewmodels, I usually have a single property associated with the selected list item’s value and I have a property that returns a list of selectlistitems. Then, I use Html.DropDownListFor(m => m.ValueProperty, Model.DropDownValues) to render the dropdown.
I imagine in your scenario, you don’t have a value corresponding to the selected listitem’s value?
Edit: Here’s an example from one of my apps…
You might have noticed the LINQ query that populates the list. In this example, I have a list (MyObjects) that was already populated by AutoMapper. You could simply return a static list if you prefer.