xVal - a validation framework for ASP.NET MVC
ASP.NET, MVC, Validation, xVal January 10th, 2009
I’ve written about validation in ASP.NET MVC more than once already. So have others (Stephen Walther, Emad Ibrahim). It’s an ongoing subject of discussion because the MVC Framework comes with great support for server-side validation (though it isn’t obvious if you come from a WebForms background), but at least as of version 1.0, it won’t ship with any built-in support for client-side validation.
I managed to get a few spare days this last week, so I decided to try and formalize lots of these ideas into something solid that you can actually use in real production code - something more than just another throwaway blog post. So here it is: xVal, an open-source project hosted on CodePlex.
What does it do?
xVal lets you link up your choice of server-side validation mechanism with your choice of client-side validation library. It guides you to fit them both into ASP.NET MVC conventions, so everything plays nicely with model binding and errors registered in ModelState.
The design goals are as follows:
- Fit in with ASP.NET MVC conventions
- Promotes a clear validation pattern that works whether or not the visitor has JavaScript enabled (graceful degradation)
- Lets you plug in your choice of server-side validation framework or custom code. The current version includes rules providers for .NET 3.5’s built-in DataAnnotations attributes as well as Castle Validator attributes, but you can also write your own IRulesProvider to attach rules programmatically or using any other .NET validation framework.
- Lets you plug in your choice of client-side validation library. The current version includes plugins for jQuery Validation as well as the native ASP.NET validation code (as used in WebForms), but you can use the standard JSON-based rules description format to write plugins for any other client-side validation library.
- Supports internationalization, so you can vary the display of error messages by the current thread UI culture.
- To be a high-quality product. xVal is built using TDD and comes with a solid set of unit tests. It uses xUnit and Moq for testing the server-side code, and Selenium RC for testing the client-side code.
The current version on Codeplex - version 0.5 – works with ASP.NET MVC Beta. It’s mostly solid and usable, though there are a few rough spots (e.g., a couple of inconsistencies to do with date formatting) that I’ll iron out soon. I also have plans to improve the internationalization somewhat to let you get error messages in other languages without having to specify them explicitly. Also, I’ll be adding support for DataAnnotations’ notion of “buddy classes” so that it works much better with the LINQ to SQL designer’s generated entity classes.
Quick tutorial
I don’t have time to document everything in xVal just yet. The basic usage pattern is supposed to be straightforward so hopefully the following tutorial won’t seem too clever or weird.
Let’s say you’ve got a model class defined as follows. Notice that we’re using attributes such as [Required], so you need to reference the System.ComponentModel.DataAnnotations.dll assembly:
public class Booking { [Required] [StringLength(15)] public string ClientName { get; set; } [Range(1, 20)] public int NumberOfGuests { get; set; } [Required] [DataType(DataType.Date)] public DateTime ArrivalDate { get; set; } }
You might add code to an ASP.NET MVC controller to create instances of this class:
public class HomeController : Controller { [AcceptVerbs(HttpVerbs.Get)] public ViewResult CreateBooking() { return View(); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult CreateBooking(Booking booking) { BookingManager.PlaceBooking(booking); return RedirectToAction("Completed"); } public ViewResult Completed() { return View(); // Displays "Thanks for booking" } }
This controller references some code in the domain tier that actually places bookings:
public static class BookingManager { public static void PlaceBooking(Booking booking) { // Todo: save to database or whatever } }
Of course, you’d also need a view for CreateBooking, containing the following markup:
<h1>Place a booking</h1>
<% using(Html.BeginForm()) { %>
<div>
Your name: <%= Html.TextBox("booking.ClientName") %>
<%= Html.ValidationMessage("booking.ClientName") %>
</div>
<div>
Number of guests: <%= Html.TextBox("booking.NumberOfGuests")%>
<%= Html.ValidationMessage("booking.NumberOfGuests")%>
</div>
<div>
Expected arrival date: <%= Html.TextBox("booking.ArrivalDate")%>
<%= Html.ValidationMessage("booking.ArrivalDate")%>
</div>
<input type="submit" />
<% } %>This is all fine, but so far, no validation is enforced.
Enforcing server-side validation
As I’ve discussed before, validation rules should go in your domain model, because the role of your model is to represent the workings of your business. It ensures that the rules will be enforced consistently, regardless of whether the UI coder remembers them or not.
At this point, reference xVal in both your domain model project and in your ASP.NET MVC project.
Let’s update BookingManager.PlaceBooking():
public static class BookingManager { public static void PlaceBooking(Booking booking) { var errors = DataAnnotationsValidationRunner.GetErrors(booking); if (errors.Any()) throw new RulesException(errors); // Business rule: Can't place bookings on Sundays if(booking.ArrivalDate.DayOfWeek == DayOfWeek.Sunday) throw new RulesException("ArrivalDate", "Bookings are not permitted on Sundays", booking); // Todo: save to database or whatever } }
Now, the model tier enforces its own validity by refusing to place bookings that don’t meet all validation and business rules. It throws a special type of exception, RulesException (defined in the xVal assembly) that passes structured error information back to the caller.
Aside: The best way of thinking about business rules, in my opinion, is that you’re validating an operation (i.e., a unit of work). For example, “documents can only be published when they have been approved by someone in the Moderator role” – this is an act of validation on the operation of publishing.
The DataAnnotations attributes don’t come with a validation runner. Here’s a very simple (and slightly naive one) referenced by the previous code block:
internal static class DataAnnotationsValidationRunner { public static IEnumerable<ErrorInfo> GetErrors(object instance) { return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>() from attribute in prop.Attributes.OfType<ValidationAttribute>() where !attribute.IsValid(prop.GetValue(instance)) select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance); } }
Finally, let’s fit in with ASP.NET MVC conventions by transferring any detected errors to ModelState:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult CreateBooking(Booking booking) { try { BookingManager.PlaceBooking(booking); } catch(RulesException ex) { ex.AddModelStateErrors(ModelState, "booking"); } return ModelState.IsValid ? RedirectToAction("Completed") : (ActionResult) View(); }
Now, because we already have Html.ValidationMessage() helpers in the view, our error messages will appear:
This is the essence of server-side validation. You validate requested operations, both in terms of model properties and arbitrary business rules expressed in C# code, and if anything is bad, you put the error information into ModelState and then re-render the view.
So far, we’ve only used xVal as a way of transferring error information from the model tier to the UI tier. The clever bit happens when we want to add client-side validation.
Applying client-side validation
xVal comes with support for native ASP.NET client-side validation and jQuery Validation. Let’s use jQuery Validation. Add jquery.validate.js (which you can download here) and xVal.jquery.validate.js (included in xVal) to your /Scripts folder, then add references in your master page:
<head>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery-1.2.6.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery.validate.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/xVal.jquery.validate.js")%>"></script>
</head>Also, import xVal’s HTML helpers by adding the following line to your web.config’s <namespaces> node:
<system.web> <pages> <namespaces> <!-- leave rest as-is --> <add namespace="xVal.Html"/> </namespaces> </pages> </system.web>
Now, all you have to do is tell xVal that you want to apply client-side validation to the controls with IDs prefixed by “booking.”. Add the following line to your view:
<%= Html.ClientSideValidation<Booking>("booking") %>That’s it! jQuery Validation will now receive and enforce the rules defined by attributes.
Of course, if someone has JavaScript turned off, they’ll still be subject to the server-side validation enforced in the model tier. Also, the business rule about not allowing bookings on Sundays will still be enforced on the server either way.
Changing client-side validation libraries
If you decide you don’t like jQuery Validation, it’s trivial to switch to a different client-side library as long as you have an xVal plugin for it. For example, to switch to native ASP.NET validation, just remove the reference to xVal.jquery.validate.js (and the other jQuery references if you want), and reference the following instead:
<script type="text/javascript" src="<%= Page.ClientScript.GetWebResourceUrl(typeof(System.Web.UI.Page), "WebForms.js") %>"></script>
<script type="text/javascript" src="<%= Page.ClientScript.GetWebResourceUrl(typeof(System.Web.UI.Page), "WebUIValidation.js") %>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/xVal.AspNetNative.js")%>"></script>Job done! You’re now using the native ASP.NET client-side validation libraries (as used by WebForms) and don’t need to use jQuery.
Download the finished demo project
What next
Over the next few weeks, I’ll try to find time to document the following features:
- How to add custom validation logic that works both on the server and on the client
- How to supply validation rules programatically or explicitly (i.e., if attributes on properties don’t meet your needs, or if you don’t like model-based validation)
- How to internationalize your validation messages
- How to write an IRulesProvider or a plugin for a client-side validation library
- How to control the placement of validation messages
- How to reuse a single rules configuration across multiple groups of form controls (e.g., when editing a list)
Comments and questions are appreciated, as well as offers to contribute to the xVal project! (For example, you could write a provider or plugin for a different server-side or client-side validation toolkit.)
In case it wasn’t obvious, xVal is hosted on CodePlex at http://xval.codeplex.com/. It’s open source, under the MS-PL license.


January 10th, 2009 at 5:41 pm
Very nicely done and very similar to the way I did it but you put it together nicely and you have a nicer name :)…
I love your blog. Keep up the good work.
Thanks.
January 10th, 2009 at 5:52 pm
This is a very elegant solution, thanks a lot for the work.
January 10th, 2009 at 5:56 pm
Awesome! I’ll try it right now:-)
January 10th, 2009 at 9:28 pm
[…] xVal - A Validation Framework for ASP.NET MVC (Steve Sanderson) […]
January 11th, 2009 at 12:01 am
Excellent, thanks for the work you did! I will try it out next week @ work and leave feedback on Codeplex.
One thing that is smart is to allow different options on both sides through plugins or implementing interfaces. imho Microsoft data annotations are inadequate, because they don’t have a runner. But then the good thing about it is that it’s part of the framework. So I hope that there will be a runner from Microsoft or a good open source runner.
January 11th, 2009 at 2:53 am
VERY cool. Nicely done, congrats!
January 11th, 2009 at 10:31 am
Very nicely done indeed!
January 11th, 2009 at 12:50 pm
Just read an article by Kirk Evans using Windows Workflow Foundation rules for entity validation (http://blogs.msdn.com/kaevans/archive/2008/11/07/using-asp-net-dynamic-data-with-the-windows-workflow-foundation-rules-engine.aspx). That would be a fascinating “enterpise-y” Rules Provider to have in your framework.
January 11th, 2009 at 2:13 pm
[…] xVal - a validation framework for ASP.NET MVC […]
January 11th, 2009 at 5:45 pm
What I was looking for!!!!! Thanks
January 11th, 2009 at 10:15 pm
Very cool. I’d like to suggest a small enhancement:
How about the RulesException returning a collection of server-side errors?
This would allow all server-side validation to be performed in one pass and prevent the slow reveal of business rule failures (fix the can’t book on Sundays error, submit and then get another error, fix that, submit, another bl**dy error!).
In any case, will be trying it out on our upcoming PoC.
January 12th, 2009 at 6:52 am
Great framework! Is the current interface stable yet? I.e. will you be changing a lot of classnames / method names and so on? I’ld really like to add this into the book I’m currently writing.
January 12th, 2009 at 8:12 am
[…] xVal - a validation framework for ASP.NET MVC - Steve Sanderson announces xVal, a validation framework for ASP.NET MVC which aims to bring together serverside and client side validation, follow ASP.NET MVC conventions and provide choice on the implementation of the client side validation. […]
January 12th, 2009 at 8:39 am
[…] xVal - a validation framework for ASP.NET MVC […]
January 12th, 2009 at 9:10 am
Thanks everyone for your kind comments.
@Andy: Interesting - I’ll check that out and may use that as an example when writing up “How to implement your own IRulesProvider”
@Andy Hitchman: RulesException already does return a collection of ErrorInfo objects. But you’re right, I could improve the example code in this blog post by adding the “Sundays” rule to the existing collection of errors (i.e., the variable called “errors” in PlaceBooking()), so it would be displayed at the same time as any other errors.
@Maarten: Thanks! Whether or not the API changes will depend on what feedback and suggestions I get. Once ASP.NET MVC Release Candidate becomes available, it should be possible for me to produce an updated version of xVal with an API that should be pretty stable for the future.
January 12th, 2009 at 10:59 am
What about the IDataErrorInfo interface to get errors straight from the model object (could still use the same runner, but that way there is no need for your ErrorInfo class, right?
January 12th, 2009 at 11:52 am
Very cool initiative ! I’ll dive in it now.
January 12th, 2009 at 12:02 pm
Great stuff, and just to say I think having the first two items in your “What Next” list would definitely be very useful in working out how to get going with it.
Anyway we’ll definitely be evaluating this for our project and nice work.
January 12th, 2009 at 12:08 pm
The best validation framework for ASP.NET MVC. Congrats for your great work.
January 12th, 2009 at 1:18 pm
Steve,
This is fantastic. A huge thank you for sharing this. Having attempted to create a model-based validation framework for MVC and getting in way over my head, I’ve been patiently waiting and hoping that someone with more insight and experience (and time!) would lead the way. So when your post came into my feed reader last night, I shouted out loud. This looks like a big step forward.
I’ll be incorporating this into my work soon and let you know if I hit any rough spots. But I’m very much looking forward to your updates on this project, and wish the best for xVal’s success in the community.
God bless,
Adam
January 12th, 2009 at 1:52 pm
This is great. I especially like that you’ve decoupled it from the actual rule providers, this way you extend to a larger audience and avoid the religious wars.
I fully expect a client side validation implementation after RTM sometime, but until then, this will be helpful.
January 12th, 2009 at 4:10 pm
Regarding your “Thoughts on validation in ASP.NET MVC applications”, how would you fit something like a unique constraint into this? Or something like a compare validator?
January 12th, 2009 at 4:53 pm
@Mike (post #16): That’s an interesting point. You could certainly tweak your server-side validation runner to take IDataErrorInfo into account. However, I don’t think it’s a suitable replacement for the ErrorInfo class because IDataErrorInfo doesn’t give you any means to discover the full set of error reports (unless you already know all the possible corresponding property names) and it doesn’t tell you which object (e.g., out of a collection of model objects) the errors relate to. I’ll review this when I get ASP.NET MVC RC because Microsoft might have changed the error reporting conventions.
@Mike (post #22): I’d implement a unique constraint in the model tier (perhaps by catching any SqlException thrown when saving a record to the database, or perhaps by checking for a clash inside a critical section with a write lock). Most of the time I don’t think it would be worthwhile to try implementing this as a client-side rule too. A client-side uniqueness check would never be totally robust anyway because a clashing value could be submitted before the user submits the form.
I haven’t yet given xVal any support for comparison-based validation rules. However, this is definitely coming soon in an upcoming version so that I can fully support all DataAnnotations attributes and Castle Validator attributes.
January 13th, 2009 at 12:13 pm
By the way, I don’t think the DataType attribute is supposed to validate, the docs state that:
“This information is then accessed by the field templates to modify how the data field is processed.”
Looking in Reflector, the IsValid method for DataTypeAttribute always returns true.
Yeah, I was a bit disappointed too, back to the RegularExpressionAttribute then.
January 13th, 2009 at 3:26 pm
@Mike
> By the way, I don’t think the DataType attribute is supposed to validate
I was thinking of providing a server-side DataAnnotations runner that has somewhat more useful behaviour for DataTypeAttribute instances. For example, [DataType(DataType.Email)] would actually check for a valid email address. Do you think that would be useful, or do you think it violates the understood semantics for a DataTypeAttribute instance?
January 14th, 2009 at 11:33 am
This is really looking useful. Thanks!
I’ve had a quick spike to try it out, against the System.ComponentModel.DataAnnotations attributes. I’ve subclassed RegularExpressionAttribute there, like [1].
How I laughed at the default error message that comes out [2] - I thought I’d share before I post myself to the dailywtf
[1]
public class EmailAttribute : RegularExpressionAttribute {
private static readonly String emailRule = @”^([a-zA-Z0-9_\-\.\’]+)@((\[[0-9]{1,3}” +
@”\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\” +
@”.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$”;
public EmailAttribute() : base(emailRule) { }
}
[2]
…
Email [jhskdhf]
The field must match the regular expression ‘^([a-zA-Z0-9_\-\.\’]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$’.
…
January 14th, 2009 at 11:45 am
@Peter: What’s wrong with that error message? It’s clear and precise
Yeah, that is how System.ComponentModel.DataAnnotations.RegularExpressionAttribute reports errors by default. Of course, it’s normal to specify your own custom ErrorMessage value for such a rule. Or in this case, to use [DataType(DataType.EmailAddress)] instead.
January 14th, 2009 at 3:13 pm
@Steve
Just found out that the Html.ClientSideValidation(”myprefix”) renders a script block that needs to be run after the page has loaded. I was putting this in the head element before the form had loaded. I had to copy your HTML helpers into my project and amend to put a $(document).ready(function(){}); wrapper around the javascript to make it work from the head. Any chance of an update with a more elegant solution?
January 14th, 2009 at 3:19 pm
@Mark - that’s a really good point and I’ll try to solve that in the next version. I don’t want the core product to rely on jQuery so I’ll need to figure out how to add a cross-browser on-DOM-ready handler without jQuery.
If you discover any other issues or want to suggest other enhancements, please use the issue tracker on CodePlex (http://www.codeplex.com/xval/WorkItem/List.aspx). That will help me keep organized. Cheers!
January 14th, 2009 at 8:31 pm
I personally don’t think you should use the datatype annotation in a different way. It’s more of a hint, although I don’t understand why it inherits from validation attribute. I just use RegularExpression to validate an email address or url.
I wrote a runner for data annotations as well, I found them to be lacking (no minimum length for strings, there’s no built in runner, datatype is just confusing). I wonder what Microsoft will do with it. ASP.NET MVC 1.0 will not have anything for validation except the basic modelstate infrastructure, but the MVC DynamicData stuff must include at least a runner and client side validation. But I don’t know if that will be suitable for our own use.
Until then, this project is really needed, so thanks again!
January 15th, 2009 at 7:49 am
[…] xVal is a validation framework I just discovered. What I liked with this framework is the promise of building a strong validation layer by picking up a server-side solution and a client-side solution. There is several possible options for both sides and xVal provides the glue between the two. The idea is to define the validation rules for each field as attributes and the system uses the same rules for both server-side and client-side validation. Very good. […]
January 15th, 2009 at 9:08 am
[…] xVal - a validation framework for ASP.NET MVC (tags: jQuery validation) […]
January 16th, 2009 at 5:03 am
[…] about validation in ASP.NET MVC more than once already. So have others (Stephen Walther, Emad Ibrahim). It’s an ongoing […]
January 16th, 2009 at 6:55 pm
very nice post…was(and still is) looking for something like this…Thanks
January 19th, 2009 at 8:13 pm
Looks great! Can this integrate with Validation Aspects (www.codeplex.com/ValidationAspects)?
January 20th, 2009 at 3:08 am
i bookmarked this article….thank you
January 20th, 2009 at 8:19 am
@Alex - looking at the source code for ValidationAspects, it certainly looks as though you could develop an xVal IRulesProvider for it. You would need to scan for attributes inheriting from ValidatorAttribute, then inspect their Factory property to see whether it was a MaximumLength or a MatchesRegex etc… Pretty much all the ValidationAspects rules correspond to existing xVal rules.
I’d be interested to hear how you get on if you try doing this yourself. The next IRulesProvider that I personally was going to write would be for NHibernate Validator, though I don’t actually know if many people use that. Maybe I should do some sort of poll to find out what server-side frameworks people most want support for.
January 20th, 2009 at 11:56 am
@Alex - there is an Emit feature introduced in the latest version of ValidationAspects that should simplify integration. I haven’t documented it yet but usage is demonstrated in the unit tests.
I’d be interested to hear how you get on also.
January 23rd, 2009 at 11:11 pm
Hi Steve, I have a quick question about xVal, does it work in medium trust? Thank you so much, -Ray.
January 26th, 2009 at 10:35 am
@Ray - xVal certainly should work fine in medium trust environments, with the exception of a certain part of the Castle Validation provider which depends on private reflection to overcome a troublesome limitation in the Castle Validation API. If you’re using the System.Web.ComponentModel.DataAnnotations provider (i.e., the default, and not Castle Validation), then there is no such issue so it should be no trouble.
January 28th, 2009 at 10:26 am
Does xVal work with ASP.NET MVC RC 1.0 ?
January 30th, 2009 at 4:16 pm
Hi Steve,
xVal looks promising, however I will wait until the NHibernate Validator is supported.
Keep up the good work!
February 1st, 2009 at 10:14 pm
+1 for NHibernate validator
February 2nd, 2009 at 8:00 am
@Larry & RC 1.0
I did have a problem using jquery validation, because the generated Ids have any ‘.’ replaced with ‘_’ so that its easier to use jquery selectors.
Change
var elemId = (elementPrefix ? elementPrefix + “.” : “”) + fieldName;
to
var elemId = (elementPrefix ? elementPrefix + “_” : “”) + fieldName;
in xval.jquery.validate.js
February 3rd, 2009 at 12:18 am
This is a great framework, many thanks for sharing
just wondering if its possible to list the errors in a validation summary instead? I have tried:
Errors:
It lists the errors, but because the messages dont include field names its obviously just a list of meaningless messages so i guess my qustions is how can i get this to work is there a way to implement a validation summary or a way to customise the error message so the validation summary makes a bit more sense using the code above
keep up the good work
February 3rd, 2009 at 12:22 am
oops the code of course was stripped out for my above comment..it is
Html.ValidationSummary(”booking”)
February 3rd, 2009 at 8:12 pm
We can also take advantage of the new Metadata functionality in DynamicData which will allow us to separate our validation rules from our domain model.
For example:
namespace DomainModel
{
[MetadataType (typeof (BookingMetadata))]
public partial class Booking
{
public string ClientName { get; set; }
public int NumberOfGuests { get; set; }
public DateTime ArrivalDate { get; set; }
}
public class BookingMetadata
{
[Required] [StringLength(15)]
public object ClientName { get; set; }
[Range(1, 20)]
public object NumberOfGuests { get; set; }
[Required] [DataType(DataType.Date)]
public object ArrivalDate { get; set; }
}
}
and one simple change to DataAnnotationsValidationRunner:
public static IEnumerable GetErrors(object instance)
{
TypeDescriptor.AddProvider (new AssociatedMetadataTypeTypeDescriptionProvider (instance.GetType ()), instance);
return from prop in TypeDescriptor.GetProperties(instance).Cast()
from attribute in prop.Attributes.OfType()
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
}
February 6th, 2009 at 6:36 pm
+1 NHibernate Validator
February 10th, 2009 at 11:17 pm
Hi Steve! I’m a real late comer to this article, and frankly quite ashamed of it! =:) Really clean implementation and love the flexibility you give between choice of frameworks (client and server). I wrote a similar article a few days after yours (and if I read yours I probably wouldn’t have bothered! lol) leveraging Emad’s approach using Castle Validator and attributes, however I suffered problems incorporating validation attributes on my domain model objects when using Linq2Sql. So if you have troubles in that regard, hopefully I can still put forward help there with my solution to it
February 12th, 2009 at 4:51 am
I am a new comer to this article too. But I am having problem with the download demo project. I don’t seem to see any clientside validation done/working in Firefox or Safari ie. http://localhost:54146/Home/CreateBooking.
I don’t have a production IIS yet, I am copying the link off IE direct to Firefox / Safari. Both browsers fail to repsonse with Clientside code, but Serverside works great. I am confused.
February 12th, 2009 at 8:03 am
@Rodrigo - it’s coming! Not sure when exactly as I’m busy working as fast as I can on my ASP.NET MVC book. Hopefully within a couple of weeks.
@Graham - thanks for the link. When you say you suffered problems with other validation approaches when adding attributes to LINQ to SQL classes, are you referring to the need for [MetadataType]? If so, xVal already supports this: http://www.codeplex.com/xval/Thread/View.aspx?ThreadId=43940
@Tony - the downloadable demo project in this post is written for ASP.NET MVC Beta. I have updated xVal to work with ASP.NET MVC Release Candidate, but the change is just in the source code for now (downloadable from http://www.codeplex.com/xval/SourceControl/ListDownloadableCommits.aspx). I am aiming to do a further proper release soon, at which point I’ll update this post. In the meantime, try using the source code version.
February 12th, 2009 at 10:41 am
Thanks for great work.
I have a question. If one form collects data from 2 models, how can I validate them?
February 12th, 2009 at 11:23 am
@Robert - In exactly the same way. Just add another Html.ClientSideValidation() helper.
February 16th, 2009 at 11:40 pm
Thanks Steve, I do mean the MetadataType! Cheers!
February 18th, 2009 at 5:46 am
Thanks Steve, this has been an amazing help.
One question. How can I attach validators to elements that don’t yet exist?
For example, in my app at the moment, a user is presented with some data, they click a button, and with JS I convert these to input fields. I want to be able to validate this data before submitting.
Any thoughts?
February 18th, 2009 at 7:49 am
Just a follow up to my previous comment, here is the solution I’m working on:
I added another overload for the ClientSideValidation helper to specify a bool for if it should output script tags.
function configEditValidation() {
<%= Html.ClientSideValidation(”Prefix”, false) %>
}
Then I can wrap it in a JS function, “configEditValidation” and just call this method when I flip into edit mode after the form elements are added to the dom.
Would still love some input / guidance as to other ways of accomplishing this.
February 18th, 2009 at 9:21 am
@Chad - that sounds like a good solution. You might like to check out the existing Html.ClientSideValidationRules() helper, because this already does more or less what you want - it produces the ruleset in JSON format, so you can then call xVal.AttachValidator(”myElementPrefix”, ruleset) to attach validation manually.
One of the things on my to-do list is documenting how to use xVal when editing a list (e.g., rows in an editable grid). This will use a similar technique to what you’ve just described. Hopefully that will make things clearer. For now though I’m using the little spare time I have for this to prepare the next xVal release which adds a whole bunch of valuable extra features.
February 19th, 2009 at 8:59 pm
Hello, Steve, I’m very much a beginner to ASP.NET MVC and a beginner programmer in general. I had a question regarding the internal static class ValidationRunner. Where exactly do I place it? Am I supposed to, somehow, add it to the DataAnnotations.dll aseembly, or create my own external class that implements it. Thanks.
February 19th, 2009 at 9:19 pm
@Richard - you can put the validation runner class anywhere in your solution. If you have a separate class library project for your domain model (or business logic, or whatever you call it) then it makes sense for it to go in there.
It isn’t possible - unless you’re Microsoft - to add extra classes to System.ComponentModel.DataAnnotations.dll
February 19th, 2009 at 9:46 pm
Thanks Stev, I went ahead and implemented it in a separate class file exactly as you show. But I get the following 2 errors:
-The type or namespace name ‘ErrorInfo’ could not be found (are you missing a using directive or an assembly reference?)
-The type or namespace name ‘IEnumerable’ could not be found (are you missing a using directive or an assembly reference?)
I’m using the assembly reference to System.Web for ErrorInfo. And if I try to implement the IEnumerable interaface by using System.Collections, I get the following error:
-The non-generic type ‘System.Collections.IEnumerable’ cannot be used with type arguments
Sorry for the long message, thanks.
February 19th, 2009 at 10:01 pm
Was able to get the genereic issue fixed, didn’t realize it had to be using System.Collections.Generic, that I had to use. I’m trying to see if there’s a similar error for the ErrorInfo message. I have a reference to Systems.Web in my project and I have a “using” directive in the class file, so I’m not sure what else might be missing.
February 19th, 2009 at 10:17 pm
Never mind, I wasn’t using the xVal directive.
February 26th, 2009 at 2:27 am
Stunningly great work!
A small question though, I don’t really see how you can enforce comparison validation in the client side… Like having too textboxes with numbers and enforcing one to be greater than the other?
February 26th, 2009 at 7:28 pm
Hello Steve, it’s Richard. I’ve gotten much more familiar with the environment and was able to successfully implement xVal validation on one field. A question though, how to you get multiple field names to display errors using only server-side validation as you show in your example above. Currently, my implementation will only catch the first error and throw that, but it will skip the rest of the errors. Helps appreciated. My complements on your work.
March 5th, 2009 at 1:50 pm
can it works on linq?
like the FluentValidation on codeplex
March 9th, 2009 at 9:05 am
@bill - if you mean “Can this work with LINQ-to-SQL-designer-generated classes?” then yes, it can. You’ll need to put your rules in some other “buddy” class using the [MetaDataType] attribute - see http://tinyurl.com/ddbckd
April 9th, 2009 at 3:46 pm
In this example you have a datatype validation attribute ([DataType(DataType.Date)]). How do you make sure xVal is handling this validation and not the model binder? I am having an issue where the model binder is catching a bad date value setting the error in ModelState and sets the date property in my model to null so xVal never gets a chance to validate the actual value.
April 20th, 2009 at 11:20 pm
How do DataAnnotations or xVal handle the concept of different requirements based on the scenario taking place (e.g. Create versus Update)? I ask because my first attempt to use straight DataAnnotations resulted in me getting a ModelState.IsValid = false with a message of “ID is Required”. The problem is, I was about to a Create the entity in question, and it’s obvious that the Primary Key is not required when you are doing a Create. It is required when doing an Update. How can I mark my properties to handle these different scenarios using DataAnnotations?
Also, I didn’t even mark my ID property as being required, so I’m curious as to how DataAnnotations figured out that it was required. I’m using LinqToSql, so I figure it’s interpreting one of the LinqToSql attributes, but I’d like to know exactly which one. If you know or could shoot me a link, I’d greatly appreciate it.
I’m about to dive into xVal because it looks great.
April 23rd, 2009 at 7:01 am
@Tim - great question, one that others may be asking too. To make sure others can find and respond, I’ve moved this discussion to http://xval.codeplex.com/Thread/View.aspx?ThreadId=54212
April 23rd, 2009 at 7:04 am
@chief7 - the model binder will register errors about unparseable strings during model binding. Bear in mind that if the string is unparseable, there’s no way it could be assigned to a .NET DateTime property anyway, so setting the date property to default(DateTime) (which you call null) is the only sensible thing that could happen by the time the request comes in.
xVal gives you client-side validation so date formatting errors will usually be caught and blocked on the client, preventing this whole problem from happening.
May 15th, 2009 at 7:13 pm
Steve,
Fantastic library. One item - is there a validation summary option for the client side script?
May 17th, 2009 at 8:42 pm
[…] I won’t go into ‘how’ to use the library, as Steve has given a great walk through here: xVal - a validation framework for ASP.NET MVC […]
May 19th, 2009 at 7:08 am
@Steve Gentile - so far xVal doesn’t create dynamic client-side validation summaries (because it’s a wrapper around whatever other client-side validation framework you’re using, and neither jQuery Validation nor ASP.NET native validation do validation summaries).
However, it’s such a commonly requested feature that I’m thinking of ways to do it, for example by making a jQuery Validation add-on that does it, and then supporting that in xVal. Not sure how quickly I’m going to be able to do it (being generally too busy at present) so if you fancy having a go at implementing it like that, I’d be delighted to accept a patch.
May 23rd, 2009 at 6:44 pm
Seeing as an Unique Validator is pretty much required for most projects, I thought of a possible solution:
ex.
public UniqueValidator : ValidationAttribute
{
public UniqueValidator(Type repositoryType, string methodName)
{
}
protected override bool Valid(object objToValidate)
{
//use reflection to instantiate the repository
//and call the method with required signature:
// public bool (string compareString) {}
}
}
1. Instantiate the repository via reflection.
2. Wrap in in a try/catch and invoke the specified method with the value.
3. Return bool indicating if valid.
I’m not entirely sure how the reflection works with xVal to generate the , but it would be possible for this to automatically add the required script (only once if an Unique validation attribute is present) with added parameters such as the method to call (Json/Ajax) server side.
Btw instead of doing as in the example to use the ValidationRunner and then do extra validation, just create a new class that inherits from ValidationAttribute and override the Valid method and add it to the metadata of the object to validate (same as required).
Another tip is to use nested classes, example:
public class MyValidation <- “wrapper”
{
public class Entity
{
public class NameValidator : ValidationAttribute
{
//override the Valid method
}
}
}
Then you can simply add a validation attribute by specifying [Entity.NameValidator].
I’ll probably implement this sometime, thanks for the great framework!
May 25th, 2009 at 8:40 pm
So every time you have to change your model you’re going to re-implementing all property attributes? How is this going to work with the entity framework when the model gets overwritten?
May 26th, 2009 at 6:53 am
@Dave - put your attributes on a “buddy class” to avoid this problem. See http://goneale.wordpress.com/2009/03/04/using-metadatatype-attribute-with-aspnet-mvc-xval-validation-framework/
June 7th, 2009 at 7:06 am
[…] xVal: A validation framework for ASP.NET MVC: Steve Sanderson writes about his cool xVal validation framework for ASP.NET MVC. This enables you to perform both client-side and server-side validation of model objects. I also highly recommend checking out his Pro ASP.NET MVC Framework book – it is absolutely fantastic. […]
June 9th, 2009 at 2:52 am
[…] xVal: A validation framework for ASP.NET MVC: Steve Sanderson 记述他非常酷的ASP.NET MVC xVal 验证框架,该框架允许你对模型对象同时做客户端和服务器端的验证。我也高度推荐你看一下他的《Pro ASP.NET MVC Framework》一书,绝对精彩。 […]
June 15th, 2009 at 2:42 pm
I’m not sure I like the idea of centralising the domain logic in my model… certainly not if I’m using schema driven development… I’d have to generate my objects and then add the validation logic using code dom. eugh.
IMO validation should execute in your managers/business layer and also be implemented there … another reason - the validation logic applied to the model may be process specific!
Thoughts?
June 16th, 2009 at 7:50 am
@Rick - all that codegen nonsense is exactly the problem with “schema driven development” and why I avoid it.
As for validation logic being process-specific - that scenario is handled trivially if both your rules and processes are owned by your model layer. For details, see http://blog.codeville.net/2008/09/08/thoughts-on-validation-in-aspnet-mvc-applications/
June 21st, 2009 at 11:01 am
[…] Steve Sanderson describes how to set it up and use in this blog article. […]
June 25th, 2009 at 7:20 am
[…] Framework (tutorial here / L2S? See […]
June 26th, 2009 at 2:38 am
This really is impressive, thank you. I setup xVal with Adam Schroeder’s IDataErrorInfo implementation and this all works perfectly.
July 2nd, 2009 at 2:37 pm
Beautiful indeed. THank you for so much working!!!. I like your blog
July 3rd, 2009 at 1:29 pm
the demo doesn’t work for me.. client-side validation doesn’t work.. only server-side validation works.
July 8th, 2009 at 7:38 am
@mmtache - it’s because this demo is pretty old and is written for ASP.NET MVC Beta. I guess you’re using the RTM version of ASP.NET MVC which isn’t compatible.
Please see the updated xVal post at http://blog.codeville.net/2009/02/27/xval-08-beta-now-released/
July 17th, 2009 at 11:52 pm
thanks!
July 29th, 2009 at 1:50 am
Creating an error validation summary when using jquery validate is relatively simple, http://docs.jquery.com/Plugins/Validation/validate#toptions has demonstrations of this using errorLabelContainer.
The difficulty in doing this with the xval / jquery integration is that the “display rules” are set in the _ensureFormIsMarkedForValidation function. Changing this from:
_ensureFormIsMarkedForValidation: function(formElement) {
if (!formElement.data(”isMarkedForValidation”)) {
formElement.data(”isMarkedForValidation”, true);
formElement.validate({
errorClass: “field-validation-error”,
errorElement: “span”,
highlight: function(element) { $(element).addClass(”input-validation-error”); },
unhighlight: function(element) { $(element).removeClass(”input-validation-error”); }
});
}
},
to:
_ensureFormIsMarkedForValidation: function(formElement) {
if (!formElement.data(”isMarkedForValidation”)) {
formElement.data(”isMarkedForValidation”, true);
formElement.validate({
errorLabelContainer: “#validationSummary”,
wrapper: “li”,
errorClass: “field-validation-error”,
errorElement: “span”,
highlight: function(element) { $(element).addClass(”input-validation-error”); },
unhighlight: function(element) { $(element).removeClass(”input-validation-error”); }
});
}
},
Changes the validation from inline to summary style ( and all you have to do is add a ul with the id validationSummary where you want the summary to appear). This does not address issue around server-side / client-side validation both appearing at the same time.
July 30th, 2009 at 6:25 pm
Great work Steve. Have you had any problems using Castle and Client Side validation? I’ve found that only my Int, Decimal, or Double gets picked up by ClientSideValidation. Strings, dates, enums and other properties do not.
For instance, this class:
public class MyClass
{
[ValidateNonEmpty]
public string MyString { get; set; }
[ValidateNonEmpty]
public int MyInt { get; set; }
}
…would only produce the following:
xVal.AttachValidator(”myClass”, {”Fields”:[{”FieldName”:”MyId”,”FieldRules”:[{”RuleName”:”DataType”,”RuleParameters”:{”Type”:”Integer”}}]}]})
My project works fine with Annotations, I just really wanted to use Castle. Any ideas?
July 31st, 2009 at 3:15 am
Great work Steve,xVal sound very cool for validation.
But now I’m using SharpArchitect with NHibernate.Validator 1.2.0.1001, I tried to see your source code to reference again to this version of NHibernate.Validator, but I got stuck with exception in snippet below:
case ValidatorMode.OverrideAttributeWithExternal:
var xmlDefinition = GetXmlDefinitionFor(type);
if (xmlDefinition != null)
result = new XmlOverAttributeClassMapping(xmlDefinition);
break;
I’m new with NHibernate.Validator, can you help to give me instruction to fix this issue so. Tks much
August 3rd, 2009 at 1:52 pm
Will it be still useful after asp.net MVC 2 updates?
August 3rd, 2009 at 1:53 pm
hm, I am talking about DataAnnotation Validation Support for asp.net MVC V2.
August 6th, 2009 at 6:15 am
Hi,
I have downloaded the sample and I notice that validation is always peformed on the server; where does the client side validation come into it? I notice there is some javascript that looks to be related rendered at the bottom of the page, but clicking the button always results in validation occurring in the Controller?
August 7th, 2009 at 12:10 am
Hi,
Just had to make some changes to the xVal.jquery.validate.js to get it to work correctly with web forms. Works very well.
August 12th, 2009 at 1:43 pm
How do I add validation messages from resource files? Ideas on loclaization of these?
August 13th, 2009 at 1:18 pm
One thing I don’t get is why exceptions are used for validation. There are always going to be validation problems on a web site so shouldn’t we plan for those by not always throwing exceptions?
August 14th, 2009 at 6:00 pm
http://stackoverflow.com/questions/1279271/will-xval-work-if-the-attributes-are-defined-on-interfaces
Will xVal work if the attributes are defined on Interfaces?
August 17th, 2009 at 6:45 pm
Could you give us an example on how to validate a collection of items, client-side?
August 19th, 2009 at 2:32 pm
why doesn’t it actually work with custom messages(client side validation) if it supports castle and jquery
August 31st, 2009 at 4:19 pm
@Shane - sounds like you haven’t enabled the Castle validation provider. Also, make sure you upgrade to the newest version of xVal. See http://blog.codeville.net/2009/02/27/xval-08-beta-now-released/ for details of both.
@Victor - who can tell? Sounds like the MVC v2 model will be similar to xVal, so if you’re using xVal now, you can probably migrate to the MVC v2 native option fairly easily, or stick with xVal if you decide it suits your requirements better.
@Dragan - use the DataAnnotations attributes - they let you specify your resource class and entry name if you want to localise your custom error messages. xVal will use the same properties to get your client-side messages in the current thread culture language.
@Ray - in .NET, exceptions are the mechanism to signal that an operation wasn’t completed. For example, a record wasn’t saved because it violated some validation conditions. Why would you want to avoid that?
@Nate - yes, if you use the “buddy class” mechanism (MetaDataTypeAttribute) to load your rules from that interface. See http://goneale.com/2009/03/04/using-metadatatype-attribute-with-aspnet-mvc-xval-validation-framework/
@CitizenBane - would love to, but blog posts take a long time to write, so there’s only so many I can manage. Hopefully I’ll cover this topic sometime soon.
@hmm - make sure you’re using xVal 0.8 or newer.
September 29th, 2009 at 6:25 pm
I don’t think this is a correct way of using exceptions. It is a validation not an “exception”, you are merely using it to indicate an error, an expected error. It has a significant performance overhead, especially in a deep code.
So it would be nice to have exception-less alternative.
October 1st, 2009 at 1:21 pm
@HeavyWave - you’re entitled to your opinion, but I disagree. In the .NET framework class library, exceptions are used to indicate that an operation (such as saving a record) could not be completed, so this is exactly the sort of scenario ideal for their use. They are *not* reserved for especially catastrophic or unusual events.
As for performance, try benchmarking the speed at which the CLR can throw and catch exceptions. Even on pitiful 5-year-old hardware, I’m sure you’ll manage 10,000 exceptions per second assuming there’s no debugger attached. This is far from your main performance bottleneck if you’re just throwing a few per request.
October 12th, 2009 at 9:05 pm
[…] Steve Sanderson ist der Autor dieses Frameworks und hat es auf seinem Blog beschrieben. […]
October 20th, 2009 at 1:10 pm
Thanks steve for this article..
could you please help me in understanding whether xval supports asp.net mvc 1.0? i am using asp.net mvc with xval .8 version.
is there any order for the jquery library?
I have added jquery files in the order below:
jquery-1.3.2.min.js
jquery.validate.js
xVal.jquery.validate.js
in few pages its breaking with some javascript error in IE 7.0, but works on Firefox.
November 2nd, 2009 at 5:15 pm
Thanks Steve for a Good Article, and the quickstart Tutorial.
I have a question, similar to Ray above.
================================
Ray Says:
August 13th, 2009 at 1:18 pm
One thing I don’t get is why exceptions are used for validation. There are always going to be validation problems on a web site so shouldn’t we plan for those by not always throwing exceptions?
================================
I have also read this, http://stackoverflow.com/questions/77127/when-to-throw-an-exception. Would it not be more efficient to use the ModelError - instantiated by the ModelError(string errorMessage ) - instead of an exception?
November 25th, 2009 at 10:14 am
Hello Steve,
we have a problem.
Your component is wild , but we are looking for some way to override some specific function in jquery.validate 1.5.5 that called showlabel , wich fires as a reaction to wrong input. we’d like it to show some image and tool tip instead of just text message in red color. The trouble is that just $.extend or even $.inherit plugin won’t do the job , because there are about 10 functions on the way , and anyway the xVal.jquery.validate uses jquery.validate specific file. Also , we would like to remain the jqueryvalidate file as it is , without changes , so that we could replace it when some more progressive version will pop out . What would you suggest , so that we could still use your plugin ?
Thanks a lot , to begin with - you are doing a great job!
November 26th, 2009 at 3:09 pm
How could I add regexp as rule?
I have the following code:
xVal.AttachValidator(jQuery.format(”messageAttributes[{0}]”, messageAttributeCounter), {
“Fields”: [
{ “FieldName”: “Link”,
“FieldRules”:
[
{ “RuleName”: “Required”, “RuleParameters”: {}, “Message”: “Link is required.” }
]
}
]
}, {});
And want to add second rule with regexp string “((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)”
Should I do it as “Custom” rule and place this string instead of “RuleParameters”?
December 1st, 2009 at 6:13 am
Very Good
December 3rd, 2009 at 2:53 pm
How to remove validation, that added via xVal.AttachValidator?
December 17th, 2009 at 2:22 pm
Pingback from http://asliborsky.blogspot.com/2009/12/all-validation-techniques-in-aspnet-mvc.html
December 21st, 2009 at 2:57 am
Elegant solution, works well
Thanks Steve for a great job !!
January 2nd, 2010 at 12:28 pm
Thanks Steve for your great job.
Is there anybody here who can help me to translate this code:
internal static class DataAnnotationsValidationRunner
{
public static IEnumerable GetErrors(object instance)
{
return from prop in TypeDescriptor.GetProperties(instance).Cast()
from attribute in prop.Attributes.OfType()
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
}
}
Regards
Alberto
January 4th, 2010 at 7:57 am
Thanks Steve for your great job.
Is there anybody here who can help me to translate in VB.NET this code:
internal static class DataAnnotationsValidationRunner
{
public static IEnumerable GetErrors(object instance)
{
return from prop in TypeDescriptor.GetProperties(instance).Cast()
from attribute in prop.Attributes.OfType()
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
}
}
Regards
Alberto
January 13th, 2010 at 2:48 am
Thank you for your great work. I am using MVC + Entity Framework in our project. With XVAL to validate user’s input, this really saves us a lot of time.
Now I have a probable. It seems that XVAL could not validate foreign key in a create or edit form because there’s no such foreign key property in entity model.
Like the code below:
[MetadataType(typeof(AngleofReport.Metadata))]
public partial class AngleofReport
{
public sealed class Metadata
{
[Required(ErrorMessage = “Your message”)]
[RegularExpression(@”^[\u4e00-\u9fa5a-zA-Z0-9\s*-_()]+$”, ErrorMessage = “”)]
public string Name
{
get;
set;
}
[Required(ErrorMessage = “Error will occur here because FK_ReportItemAngle_ID is a foreign key . “)]
public Guid FK_ReportItemAngle_ID
{
get;
set;
}
Do you have any suggesetions? How can I validate the following foreign key?
<%@ Page Title=”" Language=”C#” MasterPageFile=”~/Views/Shared/OpenWindow.Master” Inherits=”System.Web.Mvc.ViewPage” %>
* Userage:
<%=Html.ClientSideValidation()%>
Error message in the page:
The associated metadata type for type ‘Model.ReportItem’ contains the following unknown properties or fields: FK_ReportItemAngle_ID. Please make sure that the names of these members match the names of the properties on the main type.
January 21st, 2010 at 10:46 am
I am trying to use xVal, I found I need to write such a method to get the DisplayName in the entity’s attribute
public static string GetDisplayName(object instance, string propertyName)
{
return TypeDescriptor.GetProperties(instance).Find(propertyName, true).DisplayName;
}
January 21st, 2010 at 5:11 pm
Hi all!.
Im working in an project with an old UI (.Net Framework 1.1) and I was thinking to redesign the UI business validation.
I’m planning to move to .Net 3.5 (a hard project I think, asp.net pages are 1000 lines of code at least) but i was wondering if your framework can work with .Net 1.1. So i can plug it now and with the time migrate the whole application to .Net 3.5
Thanks!!!
January 21st, 2010 at 7:05 pm
Ryan, sorry, but xVal is only intended to work with ASP.NET MVC, which is itself built on .NET 3.5. It doesn’t work with WebForms 1.1 projects.
January 31st, 2010 at 7:03 am
very good ,很好。