When distributing a library you often run up against versioning problems, once facet of which is simply determining which version of that library your client is running.  Of course, each project in your solution has an AssemblyInfo.cs file which provides, among other things, the ability to set the Assembly name and version number.  Unfortunately, setting the assembly version here would require not only changing the version manually for each build (depending on your schedule), but keeping it in sync across all projects. 

There are many ways to solve this versioning problem, and in this blog post I’m going to try to explain what I think is the easiest and most flexible solution.  I will walk you through using MSBuild to create a simple build script, and I’ll even show how to (optionally) integrate with a Team City build server.  All of the code from this post can be found at https://github.com/srkirkland/BuildVersion.

Create CommonAssemblyInfo.cs

The first step is to create a common location for the repeated assembly info that is spread across all of your projects.  Create a new solution-level file (I usually create a Build/ folder in the solution root, but anywhere reachable by all your projects will do) called CommonAssemblyInfo.cs.  In here you can put any information common to all your assemblies, including the version number.  An example CommonAssemblyInfo.cs is as follows:

using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
 
[assembly: AssemblyCompany("University of California, Davis")]
[assembly: AssemblyProduct("BuildVersionTest")]
[assembly: AssemblyCopyright("Scott Kirkland & UC Regents")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("")]
 
[assembly: ComVisible(false)]
 
[assembly: AssemblyVersion("1.2.3.4")] //Will be replaced
 
[assembly: NeutralResourcesLanguage("en-US")]

 

Cleanup AssemblyInfo.cs & Link CommonAssemblyInfo.cs

For each of your projects, you’ll want to clean up your assembly info to contain only information that is unique to that assembly – everything else will go in the CommonAssemblyInfo.cs file.  For most of my projects, that just means setting the AssemblyTitle, though you may feel AssemblyDescription is warranted.  An example AssemblyInfo.cs file is as follows:

using System.Reflection;
 
[assembly: AssemblyTitle("BuildVersionTest")]

Next, you need to “link” the CommonAssemblyinfo.cs file into your projects right beside your newly lean AssemblyInfo.cs file.  To do this, right click on your project and choose Add | Existing Item from the context menu.  Navigate to your CommonAssemblyinfo.cs file but instead of clicking Add, click the little down-arrow next to add and choose “Add as Link.”  You should see a little link graphic similar to this:

image

We’ve actually reduced complexity a lot already, because if you build all of your assemblies will have the same common info, including the product name and our static (fake) assembly version.  Let’s take this one step further and introduce a build script.

Create an MSBuild file

What we want from the build script (for now) is basically just to have the common assembly version number changed via a parameter (eventually to be passed in by the build server) and then for the project to build.  Also we’d like to have a flexibility to define what build configuration to use (debug, release, etc).

In order to find/replace the version number, we are going to use a Regular Expression to find and replace the text within your CommonAssemblyInfo.cs file.  There are many other ways to do this using community build task add-ins, but since we want to keep it simple let’s just define the Regular Expression task manually in a new file, Build.tasks (this example taken from the NuGet build.tasks file).

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Go" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="RegexTransform" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
            <Items ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
        </ParameterGroup>
        <Task>
            <Using Namespace="System.IO" />
            <Using Namespace="System.Text.RegularExpressions" />
            <Using Namespace="Microsoft.Build.Framework" />
            <Code Type="Fragment" Language="cs">
                <![CDATA[
            foreach(ITaskItem item in Items) {
              string fileName = item.GetMetadata("FullPath");
              string find = item.GetMetadata("Find");
              string replaceWith = item.GetMetadata("ReplaceWith");
              
              if(!File.Exists(fileName)) {
                Log.LogError(null, null, null, null, 0, 0, 0, 0, String.Format("Could not find version file: {0}", fileName), new object[0]);
              }
              string content = File.ReadAllText(fileName);
              File.WriteAllText(
                fileName,
                Regex.Replace(
                  content,
                  find,
                  replaceWith
                )
              );
            }
          ]]>
            </Code>
        </Task>
    </UsingTask>
</Project>

If you glance at the code, you’ll see it’s really just going a Regex.Replace() on a given file, which is exactly what we need.

Now we are ready to write our build file, called (by convention) Build.proj.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Go" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="$(MSBuildProjectDirectory)\Build.tasks" />
    <PropertyGroup>
        <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
        <SolutionRoot>$(MSBuildProjectDirectory)</SolutionRoot>
    </PropertyGroup>
 
    <ItemGroup>
        <RegexTransform Include="$(SolutionRoot)\CommonAssemblyInfo.cs">
            <Find>(?&lt;major&gt;\d+)\.(?&lt;minor&gt;\d+)\.\d+\.(?&lt;revision&gt;\d+)</Find>
            <ReplaceWith>$(BUILD_NUMBER)</ReplaceWith>
        </RegexTransform>
    </ItemGroup>
 
    <Target Name="Go" DependsOnTargets="UpdateAssemblyVersion; Build">
    </Target>
 
    <Target Name="UpdateAssemblyVersion" Condition="'$(BUILD_NUMBER)' != ''">
        <RegexTransform Items="@(RegexTransform)" />
    </Target>
 
    <Target Name="Build">
        <MSBuild Projects="$(SolutionRoot)\BuildVersionTest.sln" Targets="Build" />
    </Target>
 
</Project>

Reviewing this MSBuild file, we see that by default the “Go” target will be called, which in turn depends on “UpdateAssemblyVersion” and then “Build.”  We go ahead and import the Bulid.tasks file and then setup some handy properties for setting the build configuration and solution root (in this case, my build files are in the solution root, but we might want to create a Build/ directory later).  The rest of the file flows logically, we setup the RegexTransform to match version numbers such as <major>.<minor>.1.<revision> (1.2.3.4 in our example) and replace it with a $(BUILD_NUMBER) parameter which will be supplied externally.  The first target, “UpdateAssemblyVersion” just runs the RegexTransform, and the second target, “Build” just runs the default MSBuild on our solution.

Testing the MSBuild file locally

Now we have a build file which can replace assembly version numbers and build, so let’s setup a quick batch file to be able to build locally.  To do this you simply create a file called Build.cmd and have it call MSBuild on your Build.proj file.  I’ve added a bit more flexibility so you can specify build configuration and version number, which makes your Build.cmd look as follows:

set config=%1
if "%config%" == "" (
   set config=debug
)
set version=%2
if "%version%" == "" (
   set version=2.3.4.5
)
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild Build.proj /p:Configuration="%config%" /p:build_number="%version%"

Now if you click on the Build.cmd file, you will get a default debug build using the version 2.3.4.5.  Let’s run it in a command window with the parameters set for a release build version 2.0.1.453.

image

image 

Excellent!  We can now run one simple command and govern the build configuration and version number of our entire solution.  Each DLL produced will have the same version number, making determining which version of a library you are running very simple and accurate.

Configure the build server (TeamCity)

Of course you are not really going to want to run a build command manually every time, and typing in incrementing version numbers will also not be ideal.  A good solution is to have a computer (or set of computers) act as a build server and build your code for you, providing you a consistent environment, excellent reporting, and much more.  One of the most popular Build Servers is JetBrains’ TeamCity, and this last section will show you the few configuration parameters to use when setting up a build using your MSBuild file created earlier.  If you are using a different build server, the same principals should apply.

First, when setting up the project you want to specify the “Build Number Format,” often given in the form <major>.<minor>.<revision>.<build>.  In this case you will set major/minor manually, and optionally revision (or you can use your VCS revision number with %build.vcs.number%), and then build using the {0} wildcard.  Thus your build number format might look like this: 2.0.1.{0}.  During each build, this value will be created and passed into the $BUILD_NUMBER variable of our Build.proj file, which then uses it to decorate your assemblies with the proper version.

After setting up the build number, you must choose MSBuild as the Build Runner, then provide a path to your build file (Build.proj).  After specifying your MSBuild Version (equivalent to your .NET Framework Version), you have the option to specify targets (the default being “Go”) and additional MSBuild parameters.  The one parameter that is often useful is manually setting the configuration property (/p:Configuration="Release") if you want something other than the default (which is Debug in our example). 

Your resulting configuration will look something like this:

[Under General Settings]

image

[Build Runner Settings]

image 

Now every time your build is run, a newly incremented build version number will be generated and passed to MSBuild, which will then version your assemblies and build your solution.

 

A Quick Review

Our goal was to version our output assemblies in an automated way, and we accomplished it by performing a few quick steps:

  1. Move the common assembly information, including version, into a linked CommonAssemblyInfo.cs file
  2. Create a simple MSBuild script to replace the common assembly version number and build your solution
  3. Direct your build server to use the created MSBuild script

That’s really all there is to it.  You can find all of the code from this post at https://github.com/srkirkland/BuildVersion.

Enjoy!

Last week I gave a presentation to the UC.NET User Group which provided an overview/introduction to jQuery.  Instead of using PowerPoint I created an ASP.NET MVC website and used a jQuery presentation plugin (http://www.viget.com/inspire/jquery-presentation-plugin/) to provide slide navigation and animation, which allowed me to make the presentation very interactive.

The presentation was well received so I thought I’d make the full source code, as well as a live version of the final presentation, publicly available for anyone who is interested.

Full Source Code: http://github.com/srkirkland/jQueryPresentation

Live Presentation: https://test.caes.ucdavis.edu/jQueryPresentation

Enjoy!

 

[Example Slides]

image

 image

image

ASP.NET MVC 2 improves Model Validation in a number of ways, including the addition of client side validation (ala xVal).  If you would like more information on Model Validation in ASP.NET MVC 2, see Scott Gu’s detailed post on this subject.  Out of the box ASP.NET MVC 2 includes support for DataAnnotations, and there are some extensibility points available for plugging in your own framework.

In post series I am creating my own implementations of Model Validation using NHibernate Validator (aka NHV, part of NHibernate Contrib).  This post will focus on the client-side model validation – you can find the previous post covering server-side validation here.

Note:  If you just want to see the final code, including a sample project, go to http://github.com/srkirkland/NHValModelValidators.

The Setup – Validating Customers

Below is the simple Customer class which we will use for validation.

public class Customer : BaseObject
{
    [NotNullNotEmpty]
    [Length(10)]
    public virtual string CompanyName { get; set; }
 
    [NotNullNotEmpty(Message = "Don't forget the contact name")]
    public virtual string ContactName { get; set; }
 
    [NotNullNotEmpty]
    public virtual string Country { get; set; }
 
    [NotNullNotEmpty]
    [Pattern("^[0-9]{6}")]
    public virtual string Fax { get; set; }
 
    [Range(1, 200)]
    public virtual int Age { get; set; }
}

So we are using some NotNullNotEmpty validators, a String Length validator, a Range and a Regular Expression Pattern validator for testing.

More Setup – Getting the Validator Engine

Eventually we will need to get the validation engine in order to interact with the NHibernate Validator library, and everyone probably has a different way of getting their configured engine.  For these examples (and simplicity’s sake) I’m going to use the following engine factory:

public class ValidatorEngineFactory
{
    public static ValidatorEngine ValidatorEngine
    {
        get
        {
            if (NHibernate.Validator.Cfg.Environment.SharedEngineProvider == null)
            {
                NHibernate.Validator.Cfg.Environment.SharedEngineProvider = new NHibernateSharedEngineProvider();
            }
 
            return NHibernate.Validator.Cfg.Environment.SharedEngineProvider.GetEngine();
        }
    }
}

 

Setting up the ModelValidatorProvider

The first step towards hooking up Model Validation is to create a class which inherits from System.Web.Mvc.ModelValidatorProvider.  For added convenience and utility I am going to inherit from  System.Web.Mvc.AssociatedValidatorProvider, which is a helper class provided by MVC to find associated information from your validatable fields (in our case, we want the associated validation attributes).  This class has one method you need to override, which is: 

protected override IEnumerable<ModelValidator> GetValidators(
            ModelMetadata metadata, 
            ControllerContext context, 
            IEnumerable<Attribute> attributes
        )

What we want to do with this provider is to return a list of ModelValidators that know which ModelClientValidationRule instances are associated with the given property.  Hopefully this will all become clear over the reminder of this article.

Since we are doing client-side validation and want to utilize the exiting ASP.NET MVC2 client-size validation rules then we need a way to map the NHibernate Validator constraints to MVC2 System.Web.Mvc.ModelClientValidationRule instances.  First we will create a class to help us with the mapping:

public class RuleEmitterList<TInputBase>
{
    public delegate IEnumerable<ModelClientValidationRule> RuleEmitter(TInputBase item);
 
    private readonly List<RuleEmitter> _ruleEmitters = new List<RuleEmitter>();
 
    public void AddSingle<TSource>(Func<TSource, ModelClientValidationRule> emitter) where TSource : TInputBase
    {
        _ruleEmitters.Add(x =>
                              {
 
                                  if (x is TSource)
                                  {
                                      ModelClientValidationRule rule = emitter((TSource)x);
                                      return rule == null ? null : new[] { rule };
                                  }
                                  else
                                  {
                                      return null;
                                  }
                              });
    }
 
    public IEnumerable<ModelClientValidationRule> EmitRules(TInputBase item)
    {
        foreach (var emitter in _ruleEmitters)
        {
            var emitterResult = emitter(item);
            if (emitterResult != null)
            {
                return emitterResult;
            }
        }
 
        return new ModelClientValidationRule[] { }; //No matching emitter, so return an empty set of rules
    }
}

This RuleEmitterList will take a type and “convert” that type into ModelClientValidationRules.  This technique is similar to how xVal solved a related problem.  You will see how this is used in just a minute.

In the constructor (which is run only once) we do the mapping:

public class NHibernateValidatorClientProvider : AssociatedValidatorProvider
{
    private readonly RuleEmitterList<IRuleArgs> _ruleEmitters;
 
    /// <summary>
    /// ctor: Hook up the mappings between your attributes and model client validation rules
    /// </summary>
    public NHibernateValidatorClientProvider()
    {
        _ruleEmitters = new RuleEmitterList<IRuleArgs>();
 
        _ruleEmitters.AddSingle<NotNullNotEmptyAttribute>(x => new ModelClientValidationRequiredRule(x.Message));
        _ruleEmitters.AddSingle<NotEmptyAttribute>(x => new ModelClientValidationRequiredRule(x.Message));
        _ruleEmitters.AddSingle<NotNullAttribute>(x => new ModelClientValidationRequiredRule(x.Message));
 
        _ruleEmitters.AddSingle<LengthAttribute>(
            x => new ModelClientValidationStringLengthRule(x.Message, x.Min, x.Max));
 
        _ruleEmitters.AddSingle<MinAttribute>(x => new ModelClientValidationRangeRule(x.Message, x.Value, null));
        _ruleEmitters.AddSingle<MaxAttribute>(x => new ModelClientValidationRangeRule(x.Message, null, x.Value));
 
        _ruleEmitters.AddSingle<NHibernate.Validator.Constraints.RangeAttribute>(
            x => new ModelClientValidationRangeRule(x.Message, x.Min, x.Max));
        
        _ruleEmitters.AddSingle<PatternAttribute>(x => new ModelClientValidationRegexRule(x.Message, x.Regex));
    }

So here we decided to map IRuleArgs (an NHibernate Validator interface) to their related MVC2 ModelClientValidator*Rule instances.  NonNullNotEmptyAttribute, for instance, is really a RequiredRule. Getting slightly more complex, a MaxAttribute is really a MVC2 RangeRule with the min value set to null.  All NHibernate Validator attributes that are not mapped will be ignored.

 

Implementing the ModelValidatorProvider

So now that we have our rules mapped, we have to do the actual work of inspecting our properties and emitting rules.  To do this we will basically use the NHibernate Validator library to get the constraints for every “property” and then convert our constraints to the desired rules.

/// <summary>
/// Returns the validators for the given class metadata.  This gets called for each property.
/// </summary>
/// <returns>Yield returns client validator instances with a list of rules for the current property</returns>
protected override IEnumerable<ModelValidator> GetValidators(
    ModelMetadata metadata, 
    ControllerContext context, 
    IEnumerable<Attribute> attributes
)
{
    if (metadata.ContainerType == null) yield break; //Break if there is no metadata container
 
    var engine = ValidatorEngineFactory.ValidatorEngine;
 
    var validator = engine.GetClassValidator(metadata.ContainerType);
    var constraints = validator.GetMemberConstraints(metadata.PropertyName).OfType<IRuleArgs>();
 
    var rules = new List<ModelClientValidationRule>();
 
    foreach (var constraint in constraints) //for each constraint, emit the rules for that constraint
    {
        foreach (var validationRule in _ruleEmitters.EmitRules(constraint))
        {
            validationRule.ErrorMessage = constraint.Message; //Temporarily give validation rule the error message provided by the validator
 
            validationRule.ErrorMessage = MessageOrDefault(validationRule, metadata.PropertyName); //Get a true error message if not provided
 
            rules.Add(validationRule);
        }
    }
 
    yield return new NHibernateValidatorClientValidator(metadata, context, rules);
}

There is nothing too crazy here, but we do have to be aware that one property can have many constraints, and for each constraint we must emit the proper rule (using our ruleEmitters mapping).  Then for each validation rule we must get the proper error message (described later) and add it to our list of rules for that property.  Then we yield return a simple ModelValidator instance (called NHibernateValidatorClientValidator) which just a dumb container for presenting the rules we provided.  Let’s take a look at it:

 

Implementing The Simple ModelValidator

As mentioned above, our model validator is pretty simple since our provider did all of the work.  We store the list of ModelClientValidationRule classes that was passed in to the constructor and override the GetClientValidationRules method to return this list.  We are forced to override the Validate method as well, but here we just return an empty list since we aren’t concerned about server-size validation here.

/// <summary>
/// Simple validator class which overrides GetClientValidationRules to return a list of ModelClientValidationRules, which cause client side validation
/// </summary>
public class NHibernateValidatorClientValidator : ModelValidator
{
    public NHibernateValidatorClientValidator(ModelMetadata metadata, ControllerContext controllerContext, List<ModelClientValidationRule> rules)
        : base(metadata, controllerContext)
    {
        Rules = rules;
    }
 
    protected List<ModelClientValidationRule> Rules { get; set; }
 
    /// <summary>
    /// Simply returns the supplied list of ModelClientValidationRule instances.
    /// </summary>
    /// <returns></returns>
    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        return Rules;
    }
 
    /// <summary>
    /// Returns an empty enumeration since this is not a server-side validator
    /// </summary>
    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        return Enumerable.Empty<ModelValidationResult>();
    }
}

 

Getting Good Error Messages

One tricky aspect of client validation is that NHV creates messages at runtime, so there isn’t a static message that can be displayed in advance.  If you provide NHibernate with a static message using the Message = ‘msg’ parameter then we can display that easily, but if no message is provided then we have to go another route.  So what I decided to do was workaround this by having the built-in System.ComponentModel.DataAnnotations validators provide the messages for me (of course, they rely on a static resource file under the covers, but it is internal and not directly accessible).

Our strategy will be to inspect the rule we have to see if the error message was provided.  If is was not provided, we will inspect the validation rule to and determine its type.  Using this type we will create a new instance of the corresponding DataAnnotations validator and use the message it provides.

protected string MessageOrDefault(ModelClientValidationRule rule, string propertyName)
{
    // We don't want to display the default {validator.*} messages
    if ((rule.ErrorMessage != null) && !rule.ErrorMessage.StartsWith("{validator."))
        return rule.ErrorMessage;
 
    switch (rule.ValidationType)
    {
        case "stringLength" :
            var maxLength = (int) rule.ValidationParameters["maximumLength"];
            return
                new StringLengthAttribute(maxLength).FormatErrorMessage(propertyName);
        case "required" :
            return new RequiredAttribute().FormatErrorMessage(propertyName);
        case "range" :
            var min = Convert.ToDouble(rule.ValidationParameters["minimum"]);
            var max = Convert.ToDouble(rule.ValidationParameters["maximum"]);
            return
                new System.ComponentModel.DataAnnotations.RangeAttribute(min, max).FormatErrorMessage(propertyName);
        case "regularExpression":
            var pattern = (string)rule.ValidationParameters["pattern"];
            return new RegularExpressionAttribute(pattern).FormatErrorMessage(propertyName);
        default:
            throw new NotSupportedException(
                "Only stringLength, Required, Range and RegularExpression validators are supported for generic error messages.  Add a custom error message or choose another validator type");
    }   

 

Hooking up the Client-Side ModelValidatorProvider

Now we have our new ModelValidationProvider but we still have to register it in the global.asax file:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
 
    RegisterRoutes(RouteTable.Routes);
 
    ModelValidatorProviders.Providers.Clear(); //Optional: Remove the default data annotations validations
 
    ModelValidatorProviders.Providers.Add(new NHibernateValidatorProvider()); //Server side validation provider
    ModelValidatorProviders.Providers.Add(new NHibernateValidatorClientProvider()); //Client side validation provider
}

The last line here is where we add our new client side NHibernateValidatorClientProvider.

 

Results – Validation In Action

Here is a quick action/view which should test many of the validators we configured above:

image

image

To show there is no magic here I used the awesome Html.EditorForModel() helper to create the form (the model was our Customer class shown at the top of this post).  The other important line is <% Html.EnableClientValidation(); %>, which tells ASP.NET MVC 2 to emit its client validation scripts (note: you’ll have to reference the proper javascript files – I used MicrosoftAjax.js and MicrosoftMvcValidaton.js).

Now let’s try to create the Customer and see what happens:

image

As expected, we fail validation and get pretty good error messages.  Note the “Don’t forget the contact name” custom message got through properly.

Let’s try typing into the company name box without hitting submit and see what happens:

image

Excellent!  So now we have fully integrated client and server side validation with ASP.NET MVC.

 

Show Me Code Or It Didn’t Happen

All of the code needed to get server and client side validation integrated with ASP.NET MVC 2, along with a sample project, can be found at http://github.com/srkirkland/NHValModelValidators.

Enjoy!

Alongside XSS (Cross Site Scripting) and SQL Injection, Cross-site Request Forgery (CSRF) attacks represent the three most common and dangerous vulnerabilities to common web applications today. CSRF attacks are probably the least well known but they are relatively easy to exploit and extremely and increasingly dangerous. For more information on CSRF attacks, see these posts by external link: Phil Haack and external link: Steve Sanderson.

The recognized solution for preventing CSRF attacks is to put a user-specific token as a hidden field inside your forms, then check that the right value was submitted. It's best to use a random value which you’ve stored in the visitor’s Session collection or into a Cookie (so an attacker can't guess the value).

ASP.NET MVC to the rescue

ASP.NET MVC provides an HTMLHelper called AntiForgeryToken(). When you call <%= Html.AntiForgeryToken() %> in a form on your page you will get a hidden input and a Cookie with a random string assigned.

Next, on your target Action you need to include [ValidateAntiForgeryToken], which handles the verification that the correct token was supplied.

Good, but we can do better

Using the AntiForgeryToken is actually quite an elegant solution, but adding [ValidateAntiForgeryToken] on all of your POST methods is not very DRY, and worse can be easily forgotten.

Let's see if we can make this easier on the program but moving from an "Opt-In" model of protection to an "Opt-Out" model.

Using AntiForgeryToken by default

In order to mandate the use of the AntiForgeryToken, we're going to create an ActionFilterAttribute which will do the anti-forgery validation on every POST request.

First, we need to create a way to Opt-Out of this behavior, so let's create a quick action filter called BypassAntiForgeryToken:

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false)]
public class BypassAntiForgeryTokenAttribute : ActionFilterAttribute { }

Now we are ready to implement the main action filter which will force anti forgery validation on all post actions within any class it is defined on:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class UseAntiForgeryTokenOnPostByDefault : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (ShouldValidateAntiForgeryTokenManually(filterContext))
        {
            var authorizationContext = new AuthorizationContext(filterContext.Controller.ControllerContext);
 
            //Use the authorization of the anti forgery token, 
            //which can't be inhereted from because it is sealed
            new ValidateAntiForgeryTokenAttribute().OnAuthorization(authorizationContext);
        }
 
        base.OnActionExecuting(filterContext);
    }
 
    /// <summary>
    /// We should validate the anti forgery token manually if the following criteria are met:
    /// 1. The http method must be POST
    /// 2. There is not an existing [ValidateAntiForgeryToken] attribute on the action
    /// 3. There is no [BypassAntiForgeryToken] attribute on the action
    /// </summary>
    private static bool ShouldValidateAntiForgeryTokenManually(ActionExecutingContext filterContext)
    {
        var httpMethod = filterContext.HttpContext.Request.HttpMethod;
 
        //1. The http method must be POST
        if (httpMethod != "POST") return false;
 
        // 2. There is not an existing anti forgery token attribute on the action
        var antiForgeryAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof(ValidateAntiForgeryTokenAttribute), false);
 
        if (antiForgeryAttributes.Length > 0) return false;
 
        // 3. There is no [BypassAntiForgeryToken] attribute on the action
        var ignoreAntiForgeryAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof(BypassAntiForgeryTokenAttribute), false);
 
        if (ignoreAntiForgeryAttributes.Length > 0) return false;
 
        return true;
    }
}

The code above is pretty straight forward -- first we check to make sure this is a POST request, then we make sure there aren't any overriding *AntiForgeryTokenAttributes on the action being executed. If we have a candidate then we call the ValidateAntiForgeryTokenAttribute class directly and execute OnAuthorization() on the current authorization context.

Now on our base controller, you could use this new attribute to start protecting your site from CSRF vulnerabilities.

[UseAntiForgeryTokenOnPostByDefault]
public class ApplicationController : System.Web.Mvc.Controller { }
 
//Then for all of your controllers
public class HomeController : ApplicationController {}

What we accomplished

If your base controller has the new default anti-forgery token attribute on it, when you don't use <%= Html.AntiForgeryToken() %> in a form (or of course when an attacker doesn't supply one), the POST action will throw the descriptive error message "A required anti-forgery token was not supplied or was invalid". Attack foiled!

In summary, I think having an anti-CSRF policy by default is an effective way to protect your websites, and it turns out it is pretty easy to accomplish as well.

Enjoy!

ASP.NET MVC2 will improve the built in Model Validation in a number of ways, including the addition of client side validation (ala xVal).  If you would like more information on Model Validation in ASP.NET MVC 2, see Scott Gu’s detailed post on this subject.  Out of the box ASP.NET MVC 2 will include support for DataAnnotations, and there are some extensibility points available for plugging in your own framework.

In post series I am going to create a Model Validator using NHibernate Validator (part of NHibernate Contrib).  This post will focus on the server-side model validation, and the next post will hopefully focus on adding client-side model validation.

 

The Setup – Validating Customers

Below is an example of our Customer class which we will use for validation.

public class Customer : BaseObject
{
    [NotNullNotEmpty]
    [Length(10)]
    public virtual string CompanyName { get; set; }
 
    [NotNullNotEmpty]
    public virtual string ContactName { get; set; }
 
    [NotNullNotEmpty]
    public virtual string Country { get; set; }
 
    [NotNullNotEmpty]
    public virtual string Fax { get; set; }
 
    [Range(1, 200, "Must be between 1 and 200")]
    public virtual int Age { get; set; }
}

So we are using some NotNullNotEmpty validators, a String Length validator, and a Range validator for testing.

 

More Setup – Getting the Validator Engine

Eventually we will need to get the validation engine in order to interact with the NHibernate Validator library, and everyone probably has a different way of getting their configured engine.  For these examples (and simplicity’s sake) I’m going to use the following engine factory:

public class ValidatorEngineFactory
{
    public static ValidatorEngine ValidatorEngine
    {
        get
        {
            if (NHibernate.Validator.Cfg.Environment.SharedEngineProvider == null)
            {
                NHibernate.Validator.Cfg.Environment.SharedEngineProvider = new NHibernateSharedEngineProvider();
            }
 
            return NHibernate.Validator.Cfg.Environment.SharedEngineProvider.GetEngine();
        }
    }
}

 

Implementing a ModelValidatorProvider

The first step towards hooking up Model Validation is to create a class which inherits from System.Web.Mvc.ModelValidatorProvider.  This class has one method you need to override, which is:

IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)

 

Note: GetValidators gets called for all of the properties of your model, so be prepared to have this method called multiple times.

For our implementation, we will grab the validator engine, then attempt to get the ClassValidator for the current Model Type.  The Model Type will be different every time GetValidators() is called, so we wait until we have the full class validator (classValidator != null) before returning anything.

/// <summary>
/// Server side validator provider for NHVal
/// </summary>
public class NHibernateValidatorProvider : ModelValidatorProvider
{
    /// <summary>
    /// Returns model validators for each class that can be validated.
    /// When this method is called with a non-class modelType, nothing is added to the yield return
    /// (this prevents us from validating the same properties several times)
    /// </summary>
    public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
    {
        var validationEngine = ValidatorEngineFactory.ValidatorEngine;
 
        var classValidator = validationEngine.GetClassValidator(metadata.ModelType);
 
        if (classValidator != null)
            yield return new NHibernateValidatorModelValidator(metadata, context, classValidator);
    }
}

What we are yield returning here (in the case we have a classValidator) is an instance of a new subclass of ModelValidator, which is given the classValidator and will handle the actual validation when called upon by the framework.

 

Implementing a ModelValidator

Now we need to create a class which inherits from ModelValidator, which will do the actual validation (utilizing the classValidator previously passed in).  I’ll show the final code first, and then explain it:

/// <summary>
/// Server side model validator for NHVal
/// </summary>
public class NHibernateValidatorModelValidator : ModelValidator
{
    private readonly IClassValidator _validator;
 
    public NHibernateValidatorModelValidator(ModelMetadata metadata, ControllerContext controllerContext, IClassValidator validator)
        : base(metadata, controllerContext)
    {
        _validator = validator;
    }
 
    /// <summary>
    /// Validate the model associated with this validator
    /// </summary>
    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        var validationResults = _validator.GetInvalidValues(Metadata.Model);
 
        foreach (var validationResult in validationResults)
        {
            yield return
                new ModelValidationResult { MemberName = validationResult.PropertyName, Message = validationResult.Message };
        }
    }
}

First we create a constructor which takes an IClassValidator, as well as the metadata and controllerContext (which we pass to the base ctor).  Here we just save a local instance of the validator for use later.  Eventually the framework will call Validate(), which is abstract and must be overridden.  There is also a method you can override called GetClientValidationRules(), but since we are concerned only about server-side for now, we’ll leave that for next time.

The Validate method is pretty simple—basically we grab the invalid values for the Model and transform each result into a ModelValidationResult and yield return it.

 

Hooking up the ModelValidatorProvider

Now we have a ModelValidatorProvider but ASP.NET MVC knows nothing about it, so we go to the global.asax file and register this new provider:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
 
    RegisterRoutes(RouteTable.Routes);
 
    ModelValidatorProviders.Providers.Clear(); //Optional: Remove the default data annotations validations
 
    ModelValidatorProviders.Providers.Add(new NHibernateValidatorProvider()); //Server side validation provider
}

The last line here is the most important – it is where you add the NHibernateValidatorProvider to ASP.NET MVC’s ValidatorProviders collection.

 

Results – Validation In Action

I made a quick Create action/view according to the built-in templates, which looks a little like the following:

image image

There is more markup, but the point is there is no validation code in here and it is really just using defaults.

Now, let’s try to create the Customer and see what happens:

image

Just as expected, we fail validation according to the NHibernate Validator Attributes we setup at the beginning of the post.  Notice this is all completely integrated with ASP.NET MVC – there is no validation calls in the controller or the view.

 

The Future, Conan?

I’m really happy how this turned out, but of course server-side validation is only part of the story (though an invaluable part).  Part 2 of the series will deal with creating a client-side ModelValidationProvider.

The code above is basically all you need to get server-side validation integrated with ASP.NET MVC 2, though the entire source (including a sample project) can be found at http://github.com/srkirkland/NHValModelValidators

Enjoy!

With the growing popularity of Fluent NHibernate, mapping files are being used less and less. However if you are using HBM/XML mapping files I recently dug up an old SQL script (originally written by my colleague Alan Lai, since modified slightly by myself) which might help.  The SQL Script basically generates some mapping/public property fields from an existing database that you can manually copy around into you application to save you some keystrokes.

Disclaimer: While helpful, this script is pretty simple and only handles basic properties (no keys, relationships, etc).  Still, I think it’s pretty cool and it would be selfish of me not to share it with the NHibernate world :)

 

The SQL Script

Basically the script uses the sysobjects, syscolumns, and systypes tables to inspect a database and generate a row for each table/column.  Take a look at the entire script:

SELECT table_name=sysobjects.name,
column_name=syscolumns.name,
'<property name="' + syscolumns.name + '" column="' + syscolumns.name + '" />' as mapping,
'public virtual ' +
cast (case
when systypes.name in ('varchar', 'nvarchar') then 'string'
when systypes.name = 'bit' then 'bool'
when systypes.name = 'datetime' then 'DateTime'
else systypes.name
end as varchar(10)) + ' ' + syscolumns.name + ' { get; set; }' as property,
datatype=systypes.name,
length=syscolumns.length
FROM sysobjects
JOIN syscolumns ON sysobjects.id = syscolumns.id
JOIN systypes ON syscolumns.xtype=systypes.xtype
WHERE sysobjects.xtype='U' AND systypes.name <> 'sysname'
ORDER BY sysobjects.name,syscolumns.colid

 

The Results

Running the script on the beloved Northwind database generates 133 rows, a few of which I will reproduce below:

image

Now you can open up Customers.hbm.xml and copy in the properties under the mapping column, and in Customers.cs you can do the same using the values in the property column.

Hopefully this will save you some typing if you are using NHibernate mapping files and starting from an existing database.  Enjoy!

Recently I developed a strategy which I think works well for authorizing access to user groups (Roles) without using the string names of those groups.

The problem I am trying to avoid is doing something like [Authorize(Roles=”AdminRole”)] on a controller or action since I know the role names can change & one typo can mess everything up.

Role Names

So first of all I usually have a static class which has the names & aliases for all roles in case they change:

public static class RoleNames
{
    public static readonly string Supervisor = "Supervisor";
    public static readonly string Admin = "StateOffice";
    public static readonly string ProjectAdmin = "ProjectAdmin";
    public static readonly string DelegateSupervisor = "Delegate";
}

 

This is pretty standard for me, but unfortunately I can’t just do [Authorize(Roles=RolesNames.Admin)] because attributes requires constant expressions.  So as a solution I came up with the idea of creating a custom attribute which will tightly control access based on specific role criteria.

Creating a Custom Authorize Attribute

When creating the custom authorize attribute I inherit from AuthorizeAttribute since it already contains most of the logic I need.  All I need to do is set the Roles property in the constructor to a comma delimited list of the authorized roles, and the authorize attribute base class will take care of the rest.

For example – to restrict access to just the admin role:  

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AdminOnlyAttribute : AuthorizeAttribute
{
    public AdminOnlyAttribute()
    {
        Roles = RoleNames.Admin;
    }
}

Or if you want to include the project admins as well:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AdminOnlyAttribute : AuthorizeAttribute
{
    public AdminOnlyAttribute()
    {
        var authorizedRoles = new[] {RoleNames.Admin, RoleNames.ProjectAdmin};
 
        Roles = string.Join(",", authorizedRoles);
    }
}

Usage

Then on your controller you restrict access like this

[AdminOnly]
public class AdminController : Controller{}

And it also works on an action

public class AdminController : Controller
{
    [AdminOnly]
    public ActionResult AdminOnlyAction()
    {
        return View();
    }
}

 

Enjoy!

In an earlier post I talked about writing a Transaction attribute for MVC using NHibernate (though it isn’t really NHibernate specific).  The basic idea is that when an action marked with [Transaction] is executing (OnActionExecuting) you begin a transaction, and some time later (I use OnActionExecuted, but Kazi Manzur Rashid makes a good argument for OnResultExecuted) you commit that transaction if there was no error, or rollback if there was an error.
 
With that in mind, the implementation details aren’t really important because my motivation in this post is to make every action transactional by default.  Most of the actions on any real site will require retrieving, updating, saving or removing data so as a best practice I would like the user to have to specify if they choose not to use a transaction (maybe for a static about page).
 

What I’d Like to Accomplish

Given any action method (we’ll use Index), if there is no attribute it should execute in a Transaction:

public ActionResult Index()
{
    var data = //get data
    return View(data);
}

Now if we explicitly use a [Transaction] attribute it should still execute in a Transaction:

[Transaction]
public ActionResult Index()
{
    var data = //get data
    return View(data);
}

However, we can choose to use a self-defined [HandleTransactionManually] attribute which will Not Use a Transaction:

[HandleTransactionManually]
public ActionResult Index()
{
    var data = //get data
    return View(data);
}

 

The UseTransactionByDefaultAttribute and the SuperController

To enforce “global” rules like this it is necessary for all controllers to inherit from a custom controller I call the “SuperController”.  This is a class I was using anyway for helper/common methods and I assume a lot of other people don’t inherit directly from the Controller class as well.  The SuperController just inherits from System.Web.Mvc.Controller for the purposes of this post.

Now I am going to start by making a class attribute for the SuperController (or any controller really) which will cause us to use transactions by default.  First I’ll show the implementation and then explain it:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class UseTransactionsByDefaultAttribute : ActionFilterAttribute
{
    private IDbContext _dbContext;
    private bool _delegateTransactionSupport;
 
    public IDbContext DbContext
    {
        get
        {
            if (_dbContext == null) _dbContext = SmartServiceLocator<IDbContext>.GetService();
 
            return _dbContext;
        }
    }
 
 
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _delegateTransactionSupport = ShouldDelegateTransactionSupport(filterContext);
 
        if (_delegateTransactionSupport) return;
 
        DbContext.BeginTransaction();
    }
 
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (_delegateTransactionSupport) return;
 
        if (DbContext.IsActive)
        {
            if (filterContext.Exception == null)
            {
                DbContext.CommitTransaction();
            }
            else
            {
                DbContext.RollbackTransaction();
            }
        }
    }
 
    private static bool ShouldDelegateTransactionSupport(ActionExecutingContext context)
    {
        var attrs = context.ActionDescriptor.GetCustomAttributes(typeof (TransactionalActionBaseAttribute), false);
 
        return attrs.Length > 0;
    }
}

Explanation – So this is an action filter attribute of course, and it works only on classes.  When the action executes (OnActionExecuting) I check to see if I should “delegate” the transaction support, and if so I’ll return and do nothing else.  If I am not delegating transaction support, I’ll begin the transaction.  The OnActionExecuted method does something similar and if we are not delegating it takes care of committing or doing the rollback depending on need.

The ShouldDelegateTransactionSupport is pretty interesting in that it check the custom attributes on the current action (using ActionDescriptor.GetCustomAttributes()) and if it sees any attributes that inherit from my custom TransactionalActionBaseAttribute class then it return true, meaning that we should delegate transaction support to the attributes.

This base class is pretty simple:

public class TransactionalActionBaseAttribute : ActionFilterAttribute
{
    
}

 

Handling Transactions Manually if Needed

If you want to override the default transaction then we need another attribute which will provide this support for us.  Since we have seen that inheriting from TransactionalActionBaseAttribute means we are delegated responsibility for the transaction, we can just ask for responsibility and then do nothing with it, as below

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class HandleTransactionManuallyAttribute : TransactionalActionBaseAttribute
{
}

 

Results – Show and Tell

Let’s see how this works for us.

Situation One – We don’t specify any transaction attribute and we get a transaction

public ActionResult Index()
{
    var data = //get data
    return View(data);
}

image

 

 

 

 

Situation Two – We specify a transaction attribute and we get the exact same result

[Transaction]
public ActionResult Index()
{
    var data = //get data
    return View(data);
}

image

 

 

 

 

Situation Three – We specify HandleTransactionManually and we get no transaction

[HandleTransactionManually]
public ActionResult Index()
{
    var data = //get data
    return View(data);
}

image

 

I’m a big fan of setting best practice defaults and default transactions are a good way to help get devs to use transactions as much as possible (which for many reasons is a good thing).

Enjoy!

 
      Telerik recently released their Extensions for ASP.NET MVC which include several great controls, the most immediately useful of which is their Grid control.  In the simple (and probably most common) cases the grid works by passing taking an enumerable list of objects (let’s say Northwind Orders for this example) and rendering this out as a table based on a fluent configuration.  The benefit of passing in an enumerable list is that Telerik’s Grid will use its data engine and dynamically page, sort and filter your data on the server (aka: at the database), which is a huge win.  However, by allowing the Grid to handle your actual database call you lose control of transactional support and you start using what Oren Eini refers to as “implicit transactions”.  For more information on implicit transactions and why you shouldn’t use them see http://nhprof.com/Learn/Alert?name=DoNotUseImplicitTransactions.
 

Default Grid Behavior Implementation

Following the default example on Telerik’s site, we get a configuration similar to this:
 
[The Order Controller’s List() Method]
public ActionResult List()
{
    var orders = _orderRepository.Queryable; //Return IQueryable<Order>
 
    return View(orders);
}

[The List View]

<%= Html.Grid(Model)
    .Name("Orders")
    .Columns(col =>
        {
            col.Add(order => order.OrderedBy.CompanyName);
            col.Add(order => order.ShipAddress);
            col.Add(order => order.OrderDate).Format("{0:d}");
        })
    .Pageable(x=>x.PageSize(20))
    .Sortable()
%>

 

Default Grid Behavior Results

When you run this example, you get two nice queries – one which does a count of all orders for paging purposes and one which selects the correct 20 orders from the database (sorted correctly).  You can see this in NHProf below:
 
image 
 
This all looks pretty nice, but of course those alerts are because of implicit transactions.  Let’s try adding a transaction attribute to our wrap our action in a transaction:
 
[Transaction]
public ActionResult List()
{
    var orders = _orderRepository.Queryable; //Return IQueryable<Order>
 
    return View(orders);
}
 
Running this again, we get the following:
 
image
 
Now we are getting a transaction but since we aren’t querying for the data until the action has returned the queries still take place outside of the transaction. Let’s try to fix that.
 

Transactional Options for the Grid

The general idea for wrapping the grid’s query in a transaction is that you have to open the transaction before the grid executes its render and close the transaction after it is done.  Extension methods could be a candidate here, but Render() returns void so you can’t do a commit, and regardless, for the basic grid example you don’t call render directly anyway.  Another option would be to wrap the grid in a using(transactionScope){…} method similar to using(Html.BeginForm()){…} but this seems excessive.  Or you could simply make html helpers which would begin/end transactions, but I would hate to have that in my view (I don’t think that’s the view’s responsibility).

So, with that in mind, I set off to see if I could hook into the render method and wrap it in a transaction manually.  After pouring through the Telerik source code (the extensions are on Codeplex here) I learned a few things.  First, calling Html.Telerik() causes some fairly intense control initialization code which I wouldn’t want to rewrite.  Second, calling Html.Telerik().Grid() returns an instance of GridBuilder<T>.  Finally, GridBuilder<T> has virtual methods which allow overriding and give me the hook I need to add in transactional support.

 

Creating the CustomGridBuilder<T> class

To create my custom grid builder I’ll just subclass GridBuilder<T> and add a single method – Transactional().  In the interest of space Transactional() will return a GridBuilder<T> instance so it must be called as the first method after Grid(). The full implementation is below:
 
public class CustomGridBuilder<T> : GridBuilder<T> where T : class
{
    protected bool UseTransaction { get; set; }
 
    public CustomGridBuilder(Grid<T> component) : base(component)
    {
        UseTransaction = false;
    }
 
    public GridBuilder<T> Transactional()
    {
        UseTransaction = true;
 
        return this;
    }
 
    public override void Render()
    {
        if (UseTransaction)
        {
            using (var ts = new TransactionScope())
            {
                base.Render();
 
                ts.CommitTransaction();
            }
        }
        else
        {
            base.Render();   
        }
    }
 
The big points here are that transactions are optional by default (in case you want to use custom binding, json, anonymous types, etc), and calling Transactional() sets the UseTransaction bool to true.  This causes the render method to be wrapped in a transaction scope if necessary.
 
Now we need a way to return our CustomGridBuilder<T> instead of GridBuilder<T>, so we’ll create some HtmlHelperExtensions.  You can create one for each overload of Html.Telerik().Grid() if you want, but for this example I’m only going to override the IEnumerable<T> option.
 
public static class HtmlHelperExtensions
{
    public static CustomGridBuilder<T> Grid<T>(this HtmlHelper htmlHelper, IEnumerable<T> dataModel) where T : class
    {
        var builder = htmlHelper.Telerik().Grid(dataModel);
 
        return new CustomGridBuilder<T>(builder);
    }
}

Notice here we initialize the Grid by calling the Telerik() initialization method.  This way if Telerik updates the initialization logic in future releases or even the GridBuilder logic we shouldn’t have to make any code changes at all.

We are almost done – let’s take a look at what those two classes have bought us.

 

Results!

Since we have an HtmlHelper called Grid<T> which takes an IEnumerable<T>, let’s use it to create the grid.  This code is very similar to the code we started with, adding one significant difference.
 
<%= Html.Grid(Model)
    .Transactional() //New method adding transactional support
    .Name("Orders")
    .Columns(col =>
        {
            col.Add(order => order.OrderedBy.CompanyName);
            col.Add(order => order.ShipAddress);
            col.Add(order => order.OrderDate).Format("{0:d}");
        })
    .Pageable()
    .Sortable()
%>

Of course here you can see the first method is Transactional(), and that returns a GridBuilder<T> so we can chain on any of Telerik’s methods without affecting functionality (and staying safe from future API changes).

Let’s run this example one more time (without changing) the controller at all.

image

Now that is some nice transactional SQL :)

Enjoy!

I wrote a post about a month ago about using xVal with NHibernate Validator 1.2 which solved a problem I was having upgrading the xVal ‘in-the-box’ provider to work with a newer version of NHibernate Validator. There was a caveat that my solution only worked for ValidatorMode.UseAttribute and I wouldn’t catch XML or Loquacious (or other?) validation.  This seemed to work OK, but Fabio Maulo wrote a comment to that post saying NHV has metadata which should be the same no matter which validation mode was used.

So I decided to investigate how I could get the metadata without resorting to the NHibernate.Validator.Mappings validationMode specific engines (I was using ReflectionClassMapping, but there are others like XmlClassMapping).

I think I found the solution (at least, it does work…) in the ValidatorEngine’s GetClassValidator method.  GetClassValidator takes in a System.Type and returns an IClassValidator for that Type.  Once you have the class validator, you can get constraints for any member of that class by using GetMemberConstraints(memberName).

After getting the constraints you are onto the easy part, which is basically just mapping the rules into xVal rules and the code is much the same as before.

So without further ado, here is the new ValidatorRulesProvider implementation:

public class ValidatorRulesProvider : CachingRulesProvider
{
    private readonly RuleEmitterList<IRuleArgs> _ruleEmitters;
 
    public ValidatorRulesProvider()
    {
        _ruleEmitters = new RuleEmitterList<IRuleArgs>();
 
        _ruleEmitters.AddSingle<LengthAttribute>(x => new StringLengthRule(x.Min, x.Max));
        _ruleEmitters.AddSingle<MinAttribute>(x => new RangeRule(x.Value, null));
        _ruleEmitters.AddSingle<MaxAttribute>(x => new RangeRule(null, x.Value));
        _ruleEmitters.AddSingle<RangeAttribute>(x => new RangeRule(x.Min, x.Max));
        _ruleEmitters.AddSingle<NotEmptyAttribute>(x => new RequiredRule());
        _ruleEmitters.AddSingle<NotNullNotEmptyAttribute>(x => new RequiredRule());
        _ruleEmitters.AddSingle<NotNullAttribute>(x => new RequiredRule());
        _ruleEmitters.AddSingle<PatternAttribute>(x => new RegularExpressionRule(x.Regex, x.Flags));
        _ruleEmitters.AddSingle<EmailAttribute>(x => new DataTypeRule(DataTypeRule.DataType.EmailAddress));
        _ruleEmitters.AddSingle<DigitsAttribute>(MakeDigitsRule);
    }
 
    protected override RuleSet GetRulesFromTypeCore(Type type)
    {
        var classMapping = new ValidatorEngine().GetClassValidator(type);
 
        var rules = from member in type.GetMembers()
                    where member.MemberType == MemberTypes.Field || member.MemberType == MemberTypes.Property
                    from constraint in classMapping.GetMemberConstraints(member.Name).OfType<IRuleArgs>()
                    // All NHibernate Validation validators attributes must implement this interface
                    from rule in ConvertToXValRules(constraint)
                    where rule != null
                    select new { MemberName = member.Name, Rule = rule };
 
        return new RuleSet(rules.ToLookup(x => x.MemberName, x => x.Rule));
    }
 
    private IEnumerable<Rule> ConvertToXValRules(IRuleArgs ruleArgs)
    {
        foreach (var rule in _ruleEmitters.EmitRules(ruleArgs))
        {
            if (rule != null)
            {
                rule.ErrorMessage = MessageIfSpecified(ruleArgs.Message);
                yield return rule;
            }
        }
    }
 
    private static RegularExpressionRule MakeDigitsRule(DigitsAttribute att)
    {
        if (att == null) throw new ArgumentNullException("att");
        string pattern;
        if (att.FractionalDigits < 1)
            pattern = string.Format(@"\d{{0,{0}}}", att.IntegerDigits);
        else
            pattern = string.Format(@"\d{{0,{0}}}(\.\d{{1,{1}}})?", att.IntegerDigits, att.FractionalDigits);
        return new RegularExpressionRule(pattern);
    }
 
    private static string MessageIfSpecified(string message)
    {
        // We don't want to display the default {validator.*} messages
        if ((message != null) && !message.StartsWith("{validator."))
            return message;
        return null;
    }
}

Of course in the global.asax file you just need to hook xVal and this class together like so:

xVal.ActiveRuleProviders.Providers.Add(
    new ValidatorRulesProvider(
    ValidatorMode.UseAttribute));

If you aren’t using xVal I would highly recommend it, and if you are using ASP.NET MVC and not using xVal, what are you waiting for?  They are a great match!

 

Enjoy!

More Posts « Previous page - Next page »