Data annotations can be used to validate models on both the client and the server.
On the server-side the DefaultModelBinder
will automatically validate the models that are POSTed to your action methods but it won't prevent invalid models from being POSTed. It will simply add the error to the ModelState
and set the ModelState.IsValid
property to false
(as you have discovered). That means you need to check the ModelState.IsValid
property and redisplay the form with the model if it isn't valid:
[HttpPost]
public ActionResult Edit(MyViewModel model, string button)
{
if (!ModelState.IsValid)
{
// The model isn't valid.
// Redisplay the form with the invalid model.
return View(model);
}
// If we got here it means the model is valid.
}
Redisplaying the form with the invalid model will allow any @Html.ValidationSummary()
or @Html.ValidationMessageFor(m => m.UserName)
helper methods to render their validation error messages to the page.
As far as I know, my action should not be called if the model validation fails.
This is only true if client-side validation is enabled. You can do this by adding the following appSettings to your Web.config file:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
... and adding references to the jquery.validate.js and jquery.validate.unobtrusive.js scripts to your view. This will allow JavaScript to validate the model before it is sent to the server and the validation messages will show without a page refresh (much better for the user and your server!). As @John H pointed out in the question comments, client-side validation is no substitute for server-side validation. So be sure to leave your server-side validation checks in place.