I have a ASP.NET MVC 2.0 application using Entity Framework. All my views use view models, most of them complex. Meaning…the object to be edited is a property of the view model, and not the view model itself.
I am using partial classes with data annotations, and checking ModelState.IsValid inside the POST actions in the controller.
I have a “NEW” form and an “EDIT” form for a simple object with 3 fields!
The ModelState.IsValid check works on the NEW form, and shows the correct “required field” errors, if I try to submit a blank form.
But if I load an EDIT form, and clear the values from some textboxes that are required, and submit the form, I do NOT get validation errors, I just get an exception:
Error executing child request for handler ‘System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper’.
So my question is, does ModelState.IsValid not work with an EDIT form, since perhaps it’s looking at the values from the view model object that were loaded, instead of the FormCollection?
// this one does not validate
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int accountStatusKey, AccountStatusEditViewModel model, FormCollection values)
{
if (ModelState.IsValid)
{
db.UpdateAccountStatus(accountStatusKey, values);
return RedirectToAction("States");
}
else
{
return View("Edit", model);
}
}
// this one does validate
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult New(AccountStatusNewViewModel model, FormCollection values)
{
if (ModelState.IsValid)
{
db.AddAccountStatus(values);
return View("States", new AccountStatusStatesViewModel());
}
else
{
return View("New", model);
}
}
// how I arrive AT the edit form
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Edit(int accountStatusKey)
{
return View("Edit", new AccountStatusEditViewModel(accountStatusKey));
}
// and finally, the view model code
public class AccountStatusEditViewModel : ViewModelBase
{
public AccountStatus AccountStatus { get; private set; }
public IEnumerable States { get; private set; }
public List StatusTypes { get; private set; }
public AccountStatusEditViewModel(int accountStatusKey)
{
AccountStatus = db.GetAccountStatusByKey(accountStatusKey);
States = db.GetAllStates();
StatusTypes = new List();
StatusTypes.Add("Primary Status");
StatusTypes.Add("Secondary Status");
StatusTypes.Add("External Status");
}
public AccountStatusEditViewModel()
{
}
}
// this action method does not work at all either - no db updating, no validation
// the page simply redirects to "States" view, which should only happen if the db
// was being updated, right? But nothing is changing in the DB, and the validation
// never happens.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(AccountStatusEditViewModel model)
{
if (ModelState.IsValid)
{
if (TryUpdateModel(model, "AccountStatus"))
{
return RedirectToAction("States");
}
else
{
return View("Edit", model);
}
}
else
{
return View("Edit", model);
}
}
Since the 2.0 version of MVC i’m not using the formcollection anymore.
I only use the viewmodel in the action’s parameter when i have a post, like this:
When ‘it’ can’t create my model (entered blabla for a datetime field, or when the validations are not met (i use the validation attributes from the
System.ComponentModel.DataAnnotationsnamespace) i get theModelState.IsValidequals to false.I created a blank asp.net mvc2 app, and this was the model that the standard template used for the logon action.