Model-based validation for ASP.NET MVC (concept)

MVC is definitely the way to go for the future but ASP.NET MVC Preview 4 (the latest release) still lacks in lot of different areas. One of the most essential missing features is some kind of validation and I am not the only one who needs this stuff right now. That’s why I have written a few lines for validating my forms. It’s basically a concept which is not ready for production but I want to share it with you a get some feedback.


Validation goals

All my validation stuff is built around models which minimizes the code you have to write (e.g. you don’t have to specify a property’s type twice). In this article I will assume that you use default Html helpers or helpers from MvcContrib project although it’s possible to write your own with validation in mind.

Validation of every property in your model consist of three parts according to property’s

  • type
  • name
  • and attributes

The first two types of validation works out of the box so it’s not necessary to modify your model in any way. The third one is used for more detail validation and requires marking your properties with attributes. Let’s see an example of how model can looks like:

public class TestModel
{
    int _points;
    string _name;
    string _email;

    [Required]
    [RangeValue(0, 100)]
    public int Points
    {
        get { return _points; }
        set { _points = value; }
    }

    [Required]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public string Email
    {
        get { return _email; }
        set { _email = value; }
    }
}

What will be validated?

  • ViewData["Points"]
    • if it’s an integer value
    • if it’s between 0 and 100
    • if it’s really submitted
  • ViewData["Name"]
    • if it’s really submitted
  • ViewData["Email"]
    • if it’s really an email address (empty is a valid value) (by convention)

Form setup

There is only one thing you’ll want to add to your standard forms built using Html helpers: error report. For this task I have created a new Html helper: ShowError().

<% using(Html.Form("Home", "Index")){  %>

<table>
<tr><td>Name</td><td><%= Html.TextBox("Name", ViewData.Model.Name) %></td><td><%= Html.ShowErrors(ViewData["NameErrors"]) %></td></tr>
<tr><td>Points</td><td><%= Html.TextBox("Points", ViewData.Model.Points) %></td><td><%= Html.ShowErrors(ViewData["PointsErrors"]) %></td></tr>
<tr><td>Email</td><td><%= Html.TextBox("Email", ViewData.Model.Email) %></td><td><%= Html.ShowErrors(ViewData["EmailErrors"]) %></td></tr>
<tr><td></td><td><%= Html.SubmitButton() %></td></tr>
</table>

<% } %>

Controller setup

public ActionResult Index()
{
    ViewData.Model = new TestModel();

    if (Request.HttpMethod == "POST")
    {
        IValidator validator = new Validator();
        IValidationInfo result = validator.Validate(ViewData.Model.GetType(), Request.Form);

        foreach (DictionaryEntry entry in result.Errors)
        {
            ViewData[entry.Key + "Errors"] = entry.Value;
        }

        ViewData.Model = result.Model;
    }

    return View();
}

I think that this code is almost self-explanatory. Validate() method expect two parameters: model’s type and submitted data. After the validation process all errors are then copied to ViewData. We can also use bool property result.IsValid to determine if all data are correct. My Validator also populates a strongly typed model (result.Model) with submitted values (but only those with a correct type) so I can easily grap updated model and do whatever I want (e.g. update the model in the database).

Result?

image

All code shown in this article actually works (including localization) but a lot of stuff is missing like handling relations. I can only say that it should be no problem to make it more usable.

So what do you think about it?

kick it on DotNetKicks.com

2 Responses to “Model-based validation for ASP.NET MVC (concept)”

  1. Eric Says:

    There seems to be a lot of folks who needed this. Steve Sanderson talked about one possibly back in April: http://blog.codeville.net/2008/04/30/model-based-client-side-validation-for-aspnet-mvc/

  2. Netbits » Model-based validation for ASP.NET MVC: better approach Says:

    [...] my previous post about model-based validation I introduced my concept of validating data using attributes as well as using my own HTML helpers to [...]

Leave a Reply

Hostgator is going to host .NET sites in the nearly future