This morning I’ve released xVal 0.8 (Beta). It’s a fairly substantial update – it adds the following features:

Support for NHibernate.Validator (in addition to the existing support for System.ComponentModel.DataAnnotations and Castle Validator)

Internationalization of default client-side messages

Much easier to implement custom validation logic (server-side and client-side)

Fluent syntax for defining ad-hoc validation rules directly in a view

Support for comparison validators (e.g., “PasswordConfirm” must equal “Password”)

Works with ASP.NET MVC Release Candidate

Better performance (rules are now cached per model type)

A few bugfixes

To recap, xVal is a validation framework bridge for ASP.NET MVC. It lets you use whatever server-side validation technology you prefer (and there are plenty that work well with ASP.NET MVC), and then xVal makes client-side validation happen automatically. On the client, you can enable either jQuery.Validation or ASP.NET (WebForms-style) native validation, or you can write your own plugin.

This is a “beta” quality release, in that the feature set is more or less right for 1.0. The short term goal now is not to add any more major features, but instead to focus on providing proper documentation (instead of just blog posts) and make sure it works robustly in all circumstances.

Now I’ll quickly explain the new features in 0.8.

Support for NHibernate.Validator

If you’re using NHibernate, you might also be using NHibernate.Validator. It’s a server-side validation framework that plugs directly into NHibernate’s pipeline, so you can be sure objects never reach the database unless they satisfy your rules.

xVal can now detect NHibernate.Validator rules and translate many of them into client-side rules. To make this work, assuming you already have an application that uses NHibernate.Validator, add a reference to xVal.dll and xVal.RulesProviders.NHibernateValidator.dll and then enable it in your Global.asax.cs file:

Finally, apply client-side validation in any view by using Html.ClientSideValidation():

<%= Html.ClientSideValidation<member>()%>

Note that before Visual Studio will recognize Html.ClientSideValidation(), you must either add <%@ Import Namespace="xVal.Html" %> to the top of your view, or reference the namespace globally in your web.config file:

Note that NHibernate.Validator support is pretty early at the moment. I’m interested to get any feedback about how the client-side interpretation of the rules could be improved (for example, should Date properties automatically be required?).

Internationalization of default client-side messages

It’s always been possible to internationalize the server-generated validation messages – just nominate the resource type and resource string name when defining a rule:

<head runat="server"><asp:PlaceHolder runat="server"><!-- Leave the other references as they are --><script type="text/javascript" src="<%= Url.Content("~/Scripts/xVal.Messages.en-US.js") %>"></script></asp:PlaceHolder></head>

If you run the project now, it will appear that nothing’s changed. However, simply by referencing xVal.Messages.en-US.js, you’ve told xVal to use messages defined in that file instead of using its built-in defaults. If you want to change the English messages, just edit xVal.Messages.en-US.js.

To support another language, make a copy of xVal.Messages.en-US.js, rename it to refer to the other language (e.g., xVal.Messages.es-ES.js), put that copy in your ~/Scripts/ folder, and then edit the messages so they’re in the other language.

If you want to change the language dynamically at runtime, you should add some code that varies which xVal.Messages.*.js file gets referenced, perhaps according to the current thread culture.

Update: Thanks to the community for contributing a comprehensive set of default translations. Language files for Brazilian Portuguese, Danish, Spanish, Dutch, Polish, French, German, and Swedish will be included in the next release.

Note that you should put this before any call to Html.ClientSideValidation(). Now, you’ll get client-side and server-side validation of your custom rule:

If you want to internationalize your custom rule’s message, then alter DivisibleByAttribute’s ToCustomRule() function so that it uses the CustomRule constructor that lets you specify a resource type and a resource string.

Defining Ad-Hoc Validation Rules in a View

xVal focuses on model based validation. That means you normally define rules in your model layer. However, sometimes it’s useful to throw in a few extra rules that apply only to a specific MVC view. There’s now a quick and easy way of doing this.

To try it out, download the demo project, go to the PlaceBooking.aspx view, and then edit the Html.ClientSideValidation() call to the following:

<%= Html.ClientSideValidation<booking>("booking").AddRule("Name", new RegularExpressionRule("^[a-z]{3}\\d{3}$", RegexOptions.IgnoreCase){
ErrorMessage ="Must be three letters followed by three numbers."}).AddRule("BookingDate", new RangeRule(DateTime.Now, null){
ErrorMessage ="Must be in the future."})%>

(Note: you’ll also need to add a <%@ Import Namespace="xVal.Rules"%> directive to the top of the view.)

Now, your view’s ad-hoc rules will be combined with the model rules:

If you’re the sort of person who doesn’t like model based validation at all, you could use this feature to build your complete rules configuration inline in a view. Just start with a RuleSet.Empty and add ad-hoc rules to it:

The advantages of model-based validation are clear (DRY), but this gives you extra flexibility that might come in handy.

What next?

The next step is to let people start using this and ask for feedback about how it could be improved. I’ll shy away from adding major new features right now because I don’t personally have time to manage an enormous project. I’m more interested in any bugs you might find or ways in which the current feature set could be applied better. There are already a few issues registered on Codeplex that I’ll be attending to, or better still, you could submit a patch!

Just a reminder: if you’re able to provide translations of the language file into any other major language, and if you’re happy for me to include your translation in the next release, please send it to me.Update: Thanks to everyone for all the translations. We’ve now covered all the main ones, so no more are needed.

Edit, compile, and use your own custom build with your own modifications (though this is almost certainly not necessary, as the framework gives you plenty of extensibility options)

Instead of just reading the MVC Framework source code in the abstract, one of the best ways of understanding what’s going on is to put it directly into your application’s solution. You can include the System.Web.Mvc C# project in your solution (as if you created it!), and then handily step into and out of its code while debugging, or use Visual Studio’s Go to Declaration command (or ReSharper’s) to navigate from your framework class references directly into the source. Personally, I find this very useful.

Attaching the System.Web.Mvc source code to your solution

Here’s how to include the System.Web.Mvc project source in your solution:

Download the ASP.NET MVC source code from CodePlex (be sure to get the version that corresponds to whatever version of ASP.NET MVC your app already uses). Extract the ZIP file to some convenient location.

Add System.Web.Mvc as an existing project. In Visual Studio, open your existing application, then go to File –> Add –> Existing Project. Find and select System.Web.Mvc.csproj, which will be in the source code you just extracted from the ZIP file, probably in the MVC\src\SystemWebMvc subdirectory. You’ll now have System.Web.Mvc in Solution Explorer:

Remove your app’s existing reference to System.Web.Mvc. Just find it in the list of references, right-click it, and choose Remove. This eliminates the reference to the GAC version of System.Web.Mvc (the one that was registered when you first installed ASP.NET MVC).

Add a project reference to the source code version of System.Web.Mvc. Right-click on your app in Solution Explorer, choose Add Reference, go to the Projects tab, and select System.Web.Mvc.

That’s it! You can now compile and run your application, and you’ll have a live reference to the framework source code, so you can step in and out of it, and can jump directly from any reference in your own source code to the corresponding point in the System.Web.Mvc source code. This can make debugging much easier.

Stop being so ambiguous!

Actually, there is a bit of a snag. If you have view pages without code-behind files (which is the default, since the Release Candidate), then when you try to run your app, you’ll get the following error:

You’ve now got one self-compiled instance of System.Web.Mvc.dll in your application’s \bin folder, plus the official original copy in your GAC from when you first installed ASP.NET MVC. So how is the framework supposed to decide which one to use?

Well, the only reason it considers the GAC version is that your web.config file tells it to. Go and edit your web.config file and comment out the System.Web.Mvc GAC-version reference:

Now it will only consider the version in your \bin folder, so the ambiguity ("Parser Error”) will go away.

Update: Wait, there’s more! Another config change you need to make – if you want to run a custom build of ASP.NET MVC – is in /Views/web.config (note: that’s not your top-level web.config). Since the RC, strongly-typed views depend on a clever page parser filter. Find this string:

That just tells the page compiler that it can use your custom build of ViewTypeParserFilter (and that it doesn’t have to use the GAC version). If you don’t, then strongly-typed views will throw the error “‘object’ does not contain a definition for ‘YourModelType‘”.

What about deployment?

When you come to deploy your app to another server, remember that your web.config file now doesn’t reference the GAC version of System.Web.Mvc, and the rest of your code is compiled against your custom build. To make it work on another server, you can either:

Deploy your custom build of ASP.NET MVC in the \bin folder. Your custom build of the assembly will already be in your \bin folder, so this is what will happen automatically.

Reverse the steps you just took above (which means manually editing your app’s .csproj file to reintroduce a reference to the GAC version of System.Web.Mvc, rather than the project reference). You could probably make this part of your automated build process.

I have found this technique extremely useful when trying to understand what the MVC Framework is actually doing with my application.