Monday, November 21, 2011

Validation attribute on nested list item

I'm working on some data annotation validation stuff and today I came to a requirement to validate a type nested property which is a list of string. The requirement is quite simple, just make sure every string in the list must be numeric. NumericAttribute is a custom ValidationAttribute to validate a string and to check whether it contains only numeric. Well this is a very basic example and I'm thinking futher, may be I'll need to validate different object type in the list instead of simple string and we might need different validation logic to apply on them. That leads me to this post:
Let's say I have an object definition like below:
public class Parent
{
    public List<ChildObject> Children {get;set;}
}

I want to have a validation attribute to decorate on the Children property and when the validation process happen, that attribute will validate every single ChildObject item in the list.
The attribute I want is a derived of ValidationAttribute, take different types of other Validation Attributes as the constructor parameters. And certainly, when override method IsValid, it will loop through the validation attributes set in the constructor to validate all items in the list:
public class ValidateItemUsingAttribute : ValidationAttribute
{
    private readonly Type[] _attributeTypes;

    public ValidateItemUsingAttribute(params Type[] attributes)
    {
        Check.Requires<ArgumentNullException>(attributes != null);
        Check.Requires<ArgumentException>(!attributes.Any(x => !typeof(ValidationAttribute).IsAssignableFrom(x)));
        _attributeTypes = attributes;
    }

    public override bool IsValid(object value)
    {
        if (value == null || !(value is IEnumerable) || value is string)
        {
            return true;
        }

        var index = 0;
        foreach(var item in value as IEnumerable)
        {
            foreach (var type in _attributeTypes)
            {
                var validator = Activator.CreateInstance(type) as ValidationAttribute;

                var validationResult = validator.GetValidationResult(item, new ValidationContext(item, null, null));
                if (validationResult != null)
                {
                    ErrorMessage = validationResult.ErrorMessage;
                    MemberName = string.Format("{0}[{1}]", MemberName, index);
                    return false;
                }
            }
            index++;
        }
        return true;
    }
}

Because this attribute uses Activator to create instance of other validation attribute, that require those nested validation attributes to have parameterless constructor. So for example we need to use type of StringLengthAttribute for the constructor, we may implement a derived class of StringLengthAttribute and use the new type for the constructor :D
public class Parent
{
    [ValidateItemUsing(typeof(SomeValidationAttribute), typeof(AnotherValidationAttribute))]
    public List<ChildObject> Children {get;set;}
}

Anyways, I hope this is a good idea. Cheers.

Monday, November 7, 2011

WCF Validation Engine with Data Annotation style like ASP.NET MVC

    There are many articles about WCF validation. Some are about using WCF with Microsoft Application Block, many others are about using Data Annotation. But there is not any thing like the validation engine of ASP.NET MVC. Honestly, I'm very impressed of MVC Team's work. The code is very SOLID that makes it too easy to extend without changing the implementation. There are still something i don't like in the Framework but overall, I think it's an awesome library. I have been working with ASP.NET MVC for over 2 years and now I'm having a chance to go back to WCF. I realized that WCF is designed a lot as open as MVC, there are so many extensible points in WCF that allows users to customize the services behavior, validation is one of them. I expected to find some existing code to use for WCF Validation like the one in MVC for me to copy and paste but there is not. I wanted to have a framework that we can switch any validation logic any time, just change the provider. Therefore, I decided to copy some of the implementation from MVC source code and use for this WCF validation demo.

    Firstly, I want to say about the way MVC Validation engine work. If you have ever read the MVC source code, you mush have known that in MVC, there is a ModelMetadata provider which will read the view model class and make a ModelMetaData. Then there is one or many ModelValidators which are registered before to create validator objects base the model metadata. Each validator will produce ValidationResults when validate the object. The validation process will happing during model binding and before Action method is executed. If there is an error, the error information will be append to Model State of current Controller context. And finally, in side the action method, we'll check the ModelState.IsValid to decide what to do.

    So I guess the MVC validation engine will not be able to validate nested object. But in MVC application, we still can see the error if nested object has validation error. I'm pretty sure that error is found while model binding process happen. In WCF, we don't have to worry about the model binder thing so one of the problem I have to solve is making the code validate nested object and child objects in an enumerable.

    Secondly, the ModelMetadata class and the ModelMetadataProvider classes in MVC aware of ControllerContext object which I don't want to use and there is not any reason to use it in WCF application so the next problem for me is trimming any thing related to ControllerContext.

    And finally, The MVC validation engine itself contains logic for Client validation. Again, these things will add no value for a WCF application. My aim would be copying only the code needed for validation the contract parameters in WCF.

    You may ask me why not using the classes in System.Web.Mvc.dll instead of rewriting/copying them. The answer is we cannot use that dll outside a web environment due to the assembly setting of that library.

    Alright, the way I inject validation logic into WCF method is making a IOperationBehavior as an Attribute to decorate on the action method. It's pretty much the same as other's guide. Here is the implementation:

[AttributeUsage(AttributeTargets.Method)]
public sealed class ParameterValidatorAttribute : Attribute, IOperationBehavior
{
    public ParameterValidatorAttribute()
    {
        ThrowErrorOnFirstError = false;
        ThrowErrorAfterValidation = true;
    }

    public bool ThrowErrorOnFirstError { get; set; }
    public bool ThrowErrorAfterValidation { get; set; }

    void IOperationBehavior.Validate(OperationDescription description)
    {
    }

    void IOperationBehavior.AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
    {
    }

    void IOperationBehavior.ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
    {
    }

    void IOperationBehavior.ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)
    {
        dispatch.ParameterInspectors.Add(new ParameterValidatorBehavior(ThrowErrorOnFirstError, ThrowErrorAfterValidation));
    }
}

    The ParameterValidatorBehavior implements IParameterInspector, before a service method is called, it will invoke the validation engine to validate every single input parameter. If there is a validation error, the error will be appended to ModelState object. That requires the service implementation must implement the following interface
public interface IHasModelStateService
{
    ModelState ModelState { get; set; }
}

    Here is the code of the parameter inspector:
public object BeforeCall(string operationName, object[] inputs)
{
    // validate parameters before call
    var serviceIntance = OperationContext.Current.InstanceContext.GetServiceInstance() as IHasModelStateService;
    if (serviceIntance != null)
    {
        if (serviceIntance.ModelState == null)
        {
            serviceIntance.ModelState = new ModelState();
        }
        if (serviceIntance.ModelState.Errors == null)
        {
            serviceIntance.ModelState.Errors = new List<ModelError>();
        }

        IEnumerable<ModelValidationResult> validationResults = new ModelValidationResult[] { };
        foreach (object input in inputs)
        {
            if (input != null)
            {
                ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => input, input.GetType());

                validationResults = ModelValidator.GetModelValidator(metadata).Validate(null);
                foreach (ModelValidationResult validationResult in validationResults)
                {
                    var temp = validationResult;

                    if (ThrowErrorOnFirstError)
                    {
                        throw new FaultException<ValidationFault>(new ValidationFault(new[] { temp }), "Validation error");
                    }

                    serviceIntance.ModelState.Errors.Add(new ModelError
                    {
                        MemberName = temp.MemberName,
                        Message = temp.Message
                    });
                }
            }
        }
        if (ThrowErrorAfterValidation && !serviceIntance.ModelState.IsValid)
        {
            throw new FaultException<ValidationFault>(new ValidationFault(validationResults), "Validation error");
        }
    }
    return null;
}

    Summary, to use this library. We need to do following steps:
  • Decorate the service method with [FaultContract(typeof(ValidationFault))]
  • Decorate the service method implementation or contract with [ParameterValidator], by default it will throw fault exception if there is validation error
  • Make service implementation implement interface IHasModelStateService
  • If we dont want to throw exception when validation error, we can check the ModelState.IsValid like MVC way and do whatever we want:

    if (!ModelState.IsValid)
    {
        var error = new StringBuilder();
        foreach (var e in ModelState.Errors)
        {
            error.Append(string.Format("Validation error on {0}:{1}\n", e.MemberName, e.Message));
        }
        throw new FaultException(error.ToString());
    }

    That's it. If we want to use Microsoft Validation Application Block or Fluent Validation, just replace the ModelMetadataProvider and ModelValidatorProvider like what people did with ASP.NET MVC. There is definitely alot of things to improve such as implementing an IgnoreValidationAttribute on a certain complex property of a view model or supporting the validation with validation attribute decorated inside the method contract, etc. I would happy to implement all of them when I have a chance to apply this stuff in my real project. Now it's pretty enough for my birthday night :D

Please refer to full source code here: https://github.com/vanthoainguyen/Blog/tree/master/WCF.Validation.Demo Cheers.

Saturday, October 29, 2011

Autofac, AutoMapper and custom converter with dependency injection

Whenever I work with a library or a technology, one of the question in my mind is how good is it to support dependency injection. I came back to use Autofac in a company's project recently and that question is the one I need to find the answer. Basically, Autofac is a pretty cool library to help converting between domain objects and view models. For example:
Mapper.CreateMap<Order, OrderViewModel>();

Or even better:
Mapper.CreateMap<Order, OrderViewModel>()
      .ConvertUsing<OrderConverter>();

The good thing of Automapper is that it supports very good custom converters following the way above. Most of the cases, the custom converter is just a simple class to map from fields to fields when the structure of the domain object is so complicated. Well, it's good if we can make it simple at first place but life is not that easy. The project I'm working on was created by an offshore team and everyday looking to the code, I just wonder to myself: "WTF is this shit"
The domain object is so complicated to map to the View Model by convention. ANd the ViewMOdel itself is complicated as well. It has logic to access WCF service to fetch domain data and map to itself :D. I'm spending my time to move the code to where it should be and using AutoMapper to map things is one of the steps. I hope you will never face anything like this, but in case you would and need a custom converter to access a service, this is the post for you.
Now, my need is that the OrderConverter will need to call a service method to fetch some data while mapping objects. I also want the service interface to be the dependency of the converter, it will be the parameter in OrderCOnverter constructor and when we call Mapper.Map, the dependency will be injected by a IOC library, here i use Autofac. Below is the naive implementation of OrderConverter:
public class OrderConverter : ITypeConverter<Order, OrderViewModel>
{
    private readonly IOrderService _orderService;

    public OrderConverter(IOrderService orderService)
    {
        _orderService = orderService;
    }

    public OrderViewModel Convert(ResolutionContext context)
    {
        var order = context.SourceValue as Order;
        if (order == null)
        {
            return null;
        }

        var orderDetails = _orderService.GetOrderDetailsByOrderId(order.Id);
        return new OrderViewModel
        {
            Id = order.Id,
            Details = Mapper.Map<IEnumerable<OrderDetails>, IEnumerable<OrderDetailsViewModel>>(orderDetails).ToList()
        };
    }
}

I thought Autofac should have supported the way to resolve Converter. I didn't know how to do it until reading through the code. The Mapper static class has a method Initialize and through this, we can pass in custom logic to resolve objects.
// AutoMapper initialization
Mapper.Initialize(x =>
{
     x.ConstructServicesUsing(type => container.Resolve(type));
});

The tricky thing is we need to call that method before we register mapper classes. The way I register mapper classes is using AutoFac scanning assemblies and make the mapper class implement IStartable.
var builder = new ContainerBuilder();
// startable which include mapper classes
builder.RegisterAssemblyTypes(assemblies)
       .Where(t => typeof(IStartable).IsAssignableFrom(t))
       .As<IStartable>()
       .SingleInstance();

These lines suppose to be after the Initialize method. I made the wrong mistake to put them in wrong order so the code couldn't work :D. I use the same way to register all the custom converters:
// converters
builder.RegisterAssemblyTypes(assemblies)
       .AsClosedTypesOf(typeof(ITypeConverter<, >))
       .AsSelf();

These lines would be executed in the BootStrapper before the main application run:
BootStrapper.Run();

var order = new Order {Id = 1};

try
{
    var viewModel = Mapper.Map<Order, OrderViewModel>(order);

    Console.WriteLine(string.Format("\nThere are {0} order details", viewModel.Details.Count));
}
catch (Exception ex)
{
    Console.WriteLine(ex.StackTrace);
}
finally
{
    Console.ReadLine();
}

That's it. Please check out the full application on github: https://github.com/vanthoainguyen/Blog/tree/master/TestAutoMapper

Friday, September 23, 2011

Combine logic of MVC FilterAttribute classes

    Hi mates, today I would like to write another blog about the reason why I need an Autofac IContainer as the dependency in some of my classes. In my team, we are developing a website that can allow users create and manage information about organisations. We have frontend pages for normal users to manage their organisations and we also have backend pages for the administrator to do that. So on frontend pages, we created a custom MVC filter attribute to decorate on every action methods that requires a need to check whether current user has the permission to view or edit the organisation. This filter attribute is also used in other places where we need similar authorization logic. On the other hand, we just need built-in Authorize attribute for all the admin pages. That looks like a straightforward solution, right?

    However, life is not that easy. Life is like a dick and sometime it's getting hard for no reason :D. The team decided to use MVC areas for Administrator and Organisations. That means the OrganisationManageController will be shared between those areas. Therefore, the authorization requirement would be: "Either the user is admin or the owner of the orngaisation, let him in". The first thing poped up in my mind was creating another filter attribute, inherit from Authorize filter attribute and copy the logic of my custom filter attribute which willl check the ownership. But not long after that, I realized it was so naive and ugly since the logic will be duplicated in those 2 attributes. Not only that, I was going to violate the cross-concern of the MVC Filter attributes because each of them should care and know about one and only one responsibility.

    Then I come up with the idea i'm gonna write in this blog. I decided to create another Filter attribute that implements IAuthorizeFilter. It will be resonpsible for executing all the nested IAuthorizeFilter attributes and let the user pass in if one of the filter was satisfied. The usasge will look like:
[HttpGet, Either(typeof(AuthorizeAttribute), @"Roles = ""Administrator""", typeof(CheckOwnerAttribute))]
public ActionResult Edit(ObjectId id)
{
	// ..........
}

    The EitherAttribute class will have 1 public constructor that accepts an array of objects, begin by the type of an IAuthorizeFilter, followed by it's setter information or parameters for it's constructor or both and so on. So on method OnAuthorization, it will iterate through the child filters and execute method OnAuthorization on this filter. If after executing, the filterContext.Result is modified which means the user is not authorized, i'll reset the result and go for next filter. If it's the last filter which modified the filterContext.Result, i'll just simply return. Here is the implementation:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class EitherAttribute : FilterAttribute, IAuthorizationFilter
{
    // I need a dependency of ContainerFactory here
    public Func<IContainer> ContainerFactory { get; set; }
    
    private readonly object[] _filterConstructDescriptions;

    public EitherAttribute(params object[] filterConstructDescriptions)
    {
        _filterConstructDescriptions = filterConstructDescriptions;
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        List<IAuthorizationFilter> _filters = CreateFilters(_filterConstructDescriptions);
        for (var i = 0; i < _filters.Count(); i++)
        {
            var filter = _filters[i];
            filter.OnAuthorization(filterContext);
            if (filterContext.Result == null)
            {
                return;
            }
            
            // Check next authorize filter
            if (i < _filters.Count() - 1)
            {
                filterContext.Result = null;
            }
        }
    }

    // ..........
}

    There is one interesting point to note here is the EitherAttribute has a dependency on Autofac IContainer because the nested filter will be created by Activator and if it has dependency on some services, we can use IContainer to inject require informations in. That's the reason I wrote about in previous post.

    So with this awesome attribute, I don't have to duplicate the logic across different attributes and now can use it for many different IAuthorizeFilter classes. There is only 1 limitation which is the type it support is IAuthorizeFilter only but I haven't known yet any other cases that need to extend the EitherAttribute to support other filter types.

    So please checkout the source code that includes some unit tests. Cheers

Thursday, September 22, 2011

Resolve Autofac IContainer Dependency Injection

    Today, i come to a need of using Autofac IContainer somewhere in my code. I know it's a bad practice using IContainer this way but i'm pretty sure sometime we must violate the convention. I'll show you the reason and the case on next post. Now i just say about how to have the IContainer itself resolvable in some of the classes. I guess perhaps that's the intention of the Autofac author not to make the IContainer interface to be the dependency of classes. However, we have the ServiceLocator anyway so it's not that easy to force the developer following best practices.
    Okey, here is the problem. We have the ContainerBuilder to register types, instances, etc and in the end we build the container builder to return the container instance. So If I register the instance of IContainer using the way below, it's not gonna work:
var builder = new ContainerBuilder();
// Register other dependencies in your app

IContainer container = null;
builder.RegisterInstance(container);

container = builder.Build();

The reason is we cannot register a null object. So here is the work around:
var builder = new ContainerBuilder();
// Register other dependencies in your app

IContainer container = null;
Func<IContainer> factory = () => container;
builder.RegisterInstance(factory);

container = builder.Build();

And in our code, we will make the factory to be it's dependency:
public class MyClass
{
    public MyClass(Func<IContainer> containerFactory)
    {
    }
}

Dirty, but works :D