HowTo: display validations errors in the presentation layer

This time I will talk about validation. Although there is a growing use of validation frameworks like NHV, Validation Application Block, xVal, and so on, I’ve seen a lot of people doing some weird things to display error messages in the UI.

For instance:

public static void Validate(this Controller controller, object Entity)
{
    ValidatorEngine vtor = Environment.SharedEngineProvider.GetEngine();
    InvalidValue[] errors = vtor.Validate(Entity);
    foreach (InvalidValue error in errors)
    {
        controller.ModelState.AddModelError(error.PropertyName, error.Message);
    }
}

This extension method for Asp.Net MVC takes messages from NHibernate Validator and places them in the ModelState. If you are using model-binding (which is one should really be doing with MVC), I don’t like this code because the .net framework already has something for this purpose and you don’t have to do *anything*.

The interface is IDataErrorInfo and is very ugly. But it has a great value because it works within almost any presentation technology out of the box. It works for WinForm, WPF, ASP.Net MVC and ASP.Net (non-native).

So, how to combine a validation framework with IDataErrorInfo in my classes?

First way: Very easy but coupled

Create a base entity as follows:

public class VaildatableEntity : EntityBase, IDataErrorInfo
{
    string IDataErrorInfo.this[string columnName]
    {
        get { 
            var messages = Environment.SharedEngineProvider.GetEngine()
                    .Validate(this, column)
                    .Select(iv => iv.Message)
                    .ToArray(); 
            return String.Join(Environment.NewLine, messages);
        }
    }

    string IDataErrorInfo.Error
    {
        get { 
            var messages = Environment.SharedEngineProvider.GetEngine()
                    .Validate(this)
                    .Select(iv => iv.Message)
                    .ToArray(); 

            return String.Join(Environment.NewLine, messages);
        }
    }
}

The wrong with this is that is very coupled to your validation framework, and is almost impossible to switch or test some concepts.

Second way: ServiceLocator

The second way is also easy, instead of using the validation framework directly, you write an interface like this and the implementation like this, (thanks Fabio Maulo) them you register the service in your DI container and ask that service in the ValidatableEntity through a ServiceLocator.

Third way: DynamicProxy

The third way is a little more complicated and is explained here by me. This approach is good because you don’t need anything in your domain. This is implemented in unhaddins and doesn’t depend on NHibernate Validator, this means that you can use any validation framework.


blog comments powered by Disqus
  • Categories

  • Archives