Let’s now update our application to enforce some basic input
validation rules. We’ll implement these rules on our Person model object
– and not within our Controller or our View. The benefit of implementing
the rules within our Person object is that this will ensure that the validation
will be enforced via any scenario within our application that uses the Person
object (for example: if we later added an edit scenario). This will help
ensure that we keep our code DRY and avoid repeating rules in multiple places.
ASP.NET MVC 2 enables developers to easily add declarative
validation attributes to model or viewmodel classes, and then have those
validation rules automatically be enforced whenever ASP.NET MVC performs model
binding operations within an application. To see this in action, let’s
update our Person class to have a few validation attributes on it. To do
this we’ll add a “using” statement for the
“System.ComponentModel.DataAnnotations” namespace to the top of the file – and
then decorate the Person properties with [Required], [StringLength], [Range],
and [RegularExpression] validation attributes (which are all implemented within
that namespace):
Note: Above we are explicitly specifying error
messages as strings. Alternatively you can define them within resource files
and optionally localize them depending on the language/culture of the incoming
user. You can learn more about how to localize validation error messages here.
Now that we’ve added the validation attributes
to our Person class, let’s re-run our application and see what happens when we
enter bogus values and post them back to the server:
Notice above how our application now has a
decent error experience. The text elements with the invalid input are
highlighted in red, and the validation error messages we specified are
displayed to the end user about them. The form is also preserving the
input data the user originally entered – so that they don't have to refill
anything. How though, you might ask, did this happen?
To understand this behavior, let’s look at the
Create action method that handles the POST scenario for our form:
When our HTML form is posted back to the
server, the above method will be called. Because the action method
accepts a “Person” object as a parameter, ASP.NET MVC will create a Person
object and automatically map the incoming form input values to it. As
part of this process, it will also check to see whether the DataAnnotation
validation attributes for the Person object are valid. If everything is
valid, then the ModelState.IsValid check within our code will return true – in
which case we will (eventually) save the Person to a database and then redirect
back to the home-page.
If there are any validation errors on the
Person object, though, our action method redisplays the form with the invalid
Person. This is done via the last line of code in the code snippet above.
The error messages are then displayed within
our view because our Create form has <%= Html.ValidationMessageFor() %>
helper method calls next to each <%= Html.TextBoxFor() %> helper.
The Html.ValidationMessageFor() helper will output the appropriate error
message for any invalid model property passed to the view:
The nice thing about this pattern/approach is
that it is pretty easy to setup – and it then allows us to easily add or change
validation rules on our Person class without having to change any code within
our controllers or views. This ability to specify the validation rules
one place and have it be honored and respected everywhere allows us to rapidly
evolve our application and rules with a minimum amount of effort and keep our
code very DRY.