eWorld.UI - Matt Hawley

Ramblings of Matt

MVC UI Validation Framework

April 2, 2008 16:36 by matthaw

The last few days I've been working on a MVC UI validation framework that closely follows that of ASP.NET. While my implementation is only in it's baby steps, I decided I would post it to the MVC Contrib project, and follow as much standards as what they have. Overall, the framework is very simple and straight forward in it's use.

Here were my requirements:

  1. It must closely match the ASP.NET UI validation framework.
  2. It should support all of the ASP.NET validators in their minimalistic implementation.
  3. It should require very minimal script inclusion or code to make this happen.
  4. It should only by a client side framework as you should be protecting your data on the server side through normal validations.

What I came up with, includes:

  1. It utilizes the ASP.NET UI validation framework by leveraging the WebUIValidation.js file (emitted through WebResource.axd).
  2. It supports all of the validators, with extended support for validation groups:
    1. RequiredValidator
    2. RegularExpressionValidator
    3. RangeValidator (currently does not support Date or Currency data types)
    4. CompareValidator
    5. CustomValidator
  3. It exposes 2 script inclusion calls, and 1 form validation setup call
    1. ValidatorRegistrationScripts() - Will render the WebUIValidation.js script, and scripts for form validation upon submission. This should be placed within the head tag.
    2. ValidatorInitializationScripts() - Will render all of the "expando" attributes for all validators upon the page and any initialization calls to set things up. This should be placed at the very end of your page before the closing body tag.
    3. FormValidation() - Will return an IDictionary object containing the "onsubmit" attribute. This should be called when creating your <form> tag.
  4. It is only a client-side framework leveraging ASP.NET's WebUIValidation.js

Since you now have an idea of the requirements and what was met, here's an example of it in action:

   1:  <%@ Import Namespace="MvcContrib.UI.Html" %>
   2:  <html>
   3:     <head>
   4:        <%= Html.Form().ValidatorRegistrationScripts() %>
   5:     </head>
   6:     <body>
   7:        <% using(Html.Form<MyController>(c => c.Save(), FormMethod.Post, Html.Form().FormValidation())) { %>
   8:        First Name: <%= Html.TextBox("firstName") %>
   9:        <%= Html.Form().RequiredValidator("firstNameRequired", "firstName", "First Name is Required.") %>
  10:        <%= Html.Form().RegularExpressionValidator("firstNameRegex", "firstName", "[a-zA-Z]*", "First Name can only contain letters.") %>
  11:        <br />
  12:        Age: <%= Html.TextBox("age") %>
  13:        <%= Html.Form().RequiredValidator("ageRequired", "age", "Age is Required.") %>
  14:        <%= Html.Form().RegularExpressionValidator("ageRegex", "age", "[0-9]*", "Age can only be numeric.") %>
  15:        <%= Html.Form().RangeValidator("ageRange", "age", "18", "35", ValidationDataType.Integer, "Age is not in target range of 18-35.") %>
  16:        <br />
  17:        <%= Html.SubmitButton("submit", "Save") %>
  18:        <% } %>
  19:        <%= Html.Form().ValidatorInitializationScripts() %>
  20:     </body>
  21:  </html>

At this point, I've posted it as a patch to MVC Contrib project, and hoping they apply it Smile. If you would like to get your hands on it, check out the patches page, mine is #1063. Please let me know your input, I tried making it as simple as possible to use, and I believe I've achieved that.

Update: My patch has been applied by Eric :) Get the latest build (>= 0.0.1.96) it if you'd like to check this out. Also, let me know of any issues you may find by logging bugs on the CodePlex site.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

April 4. 2008 23:37

This is very impressive, Matt.

Now what would be nice is if the validation rules came from the model. Using the example from your code, let's say you had a Person class which had a method named GetValidators that returned an array of ValidationRules. That method could look like this:

public List<ValidatedProperty> GetValidators()
{
return new List<ValidatedProperty>{

new ValidatedProperty("firstName", new List<ValidationRule>{
new RequiredFieldValidation(),
new RegexValidation( "[a-zA-Z]", "First Name can only contain letters" )
},

new ValidatedProperty( "age", new List<ValidationRule>{
new RequiredFieldValidation( "Age is Required." ),
new RegexValidation( "[0-9]*" ),
new RangeValidation<int>( 18, 35 )
}

};
}

Now it would be easy to pass the model into the view to construct the validation dynamically, like:

First Name: <%= Html.TextBox("firstName") %>
<%= Html.Validate( "firstName", Validations["firstName"] ) %>

The benefit of doing it like this is in the controller's Save() action, we could also reconstitute the validators from the model and double-check on the server side. Maybe something like:

public void Save()
{
Person person = new Person( Request.Form["firstName"] );
Binding.UpdateFrom( person, Request.Form );
if( Validator.IsValid( person.GetValidators() )
person.Save()
else
// throw an exception or whatever
}

What do you think? Sorry for the lack of formatting... =/

Troy Goode

April 5. 2008 17:19

I like that idea, we'll see when it can be implemented Smile

matthaw

April 7. 2008 17:40

Hey Matt - as a longtime user of your eWorld stuff it's nice to see you throw some love at MVC! Have some thoughts for you...

1) Agree with other points that you don't want to have to declare validation for "Last name can't be NULL" in every page that takes a last name (Registration, Ship To, Bill To, Contact, whatever). There's a lot that we know with the model already - in fact if you're a SubSonic user SmileSmileSmileSmile you know the lengths, nullability, datatypes... etc...
2) It might be interesting to creat a validation lib that works specifically with other frameworks. SubSonic is one of em Smile. You could also do a custom thing for LinqToSql (I have some code... email me!)

That would rock Smile

Rob Conery

April 7. 2008 18:59

Pingback from code-inside.de

Wöchentliche Rundablage: ASP.NET MVC, Silverlight 2, .NET, RegEx, .NET, Icons, CSS, UI | Code-Inside Blog

code-inside.de

April 8. 2008 02:55

I agree with Troy. I think the Model is the correct place to put the validation. Consider something like an attribute style validation mechanism like the Application Validation Block. By doing this you allow all views to leverage the same validation. When the view is rendered, you could interrogate the model for the validation attributes and inject those into the view for the pieces of the model that are presented in a form.

Scott Prugh

April 8. 2008 13:32

Pingback from mhinze.com

Links Today (2008-04-08)

mhinze.com

April 24. 2008 14:14

Pingback from weblogs.asp.net

47 ASP.NET MVC Resources to Rock Your Development - Craig Shoemaker

weblogs.asp.net

May 9. 2008 06:30

I m having problem using the MVC Contrib getting following error any assitance will be helpful for me

The type 'System.Web.Mvc.ComponentController' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'

<%=Html.Form().ValidatorRegistrationScripts %>

Muhammad Taufiq Yusuf

May 23. 2008 23:09

css textboxt ınput (textfield) style - examples - -
www.css-lessons.ucoz.com/textbox-css-examples.htm

chester..

Add comment


 

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

July 4. 2008 18:38



Copyright © 2000 - 2008 , Excentrics World