ASP.NET: How to avoid ArgumentNullException in StructureMap controller factory

I am using StructureMap as my IoC container. In my ASP.NET MVC web application I have controller factory based on StructureMap. I found interesting problem – when running my web application on development web server I get ArgumentNullException with every request to some controller action. In this posting I will describe why it is happening and how to avoid it.

Here is the early version of my controller factory. I found it from Shiju Varghese’s blog posting ASP.NET MVC Tip: Dependency Injection with StructureMap.


public class StructureMapControllerFactory : 
DefaultControllerFactory
{
    protected override IController GetControllerInstance(
RequestContext requestContext, Type controllerType)
    {
        try
        {
            var controller = ObjectFactory.GetInstance(controllerType);
            return controller as Controller;
        }
        catch
        {
            Debug.WriteLine(ObjectFactory.WhatDoIHave());
            throw;
        }
    }
}

Well… here’s the little gotcha. There is condition when controllerType is null. You can read more from Stack Overflow thread StructureMap error when invalid controller. ASP.NET development web server (and also IIS with wildcard mapping) handle all requests through ASP.NET handlers. One thing that is asked for every controller action by some browsers is favicon. As ASP.NET MVC cannot detect controller – there is no controller for favicon – the type of controller is null. So, we need a little bugfix to controller factory.


public class StructureMapControllerFactory : 
DefaultControllerFactory
{
    protected override IController GetControllerInstance(
RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return null;
 
        try
        {
            var controller = ObjectFactory.GetInstance(controllerType);
            return controller as Controller;
        }
        catch
        {
            Debug.WriteLine(ObjectFactory.WhatDoIHave());
            throw;
        }
    }
}

You may say that it should be handled by routing and you are right – you can do it. But handling all types of requests through routing is not good idea. If you read Stack Overflow thread referred above you can see that same problem occurs if user makes typo to controller name when inserting URL to browser manually. My solution here is better because it handles all such cases when controller type is null and causes less errors to handle and log.

No Comments