doogle
doogle

Reputation: 3406

How does DefaultControllerFactory Handle Content Requests

I'm working with the ASP.Net MVC 3 framework and I'm integrating dependency injection into the application. I'm trying to create a custom controller factory. The biggest issue I'm having at this moment is my implementation of IControllerFactory.CreateController gets passed requests for things like css, javascript, and other content files which subsequently causes it to throw an exception as the type for "Scripts/html5.js" doesn't exist. The code was inherited to me, so save any criticism you may have as to the very haphazard state. Here is the implementation:

    public virtual IController CreateController(RequestContext requestContext, string controllerName)
    {
        if (requestContext == null)
        {
            throw new ArgumentNullException("requestContext");
        }

        if (String.IsNullOrEmpty(controllerName))
        {
            throw new ArgumentException("Value cannot be null or empty", "controllerName");
        }

        this.RequestContext = requestContext;
        try
        {
            return container.Resolve<IController>(controllerName.ToLower());
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.Message);
            return innerFactory.CreateController(requestContext, controllerName);
        }
    }

Upvotes: 1

Views: 2083

Answers (2)

doogle
doogle

Reputation: 3406

I was able to solve this by inheriting from the DefaultControllerFactory instead of implementing IControllerFactory in its entirety:

public class MyControllerFactory : DefaultControllerFactory

Then I only needed to override the GetControllerInstance method to hook in and return any instances from my Unity container:

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        IController controller = null;
        if (controllerType == null)
        {
            throw new HttpException(404, String.Format("The controller for path '{0}' could not be found or it does not implement IController.", requestContext.HttpContext.Request.Path));
        }

        if (!typeof(IController).IsAssignableFrom(controllerType))
        {
            throw new ArgumentException(String.Format("Type requested is not a controller: {0}", controllerType.Name), "controllerType");
        }

        try
        {
            if (this.container.IsRegistered(controllerType))
            {
                controller = this.container.Resolve(controllerType) as IController;
            }
            else
            {
                controller = base.GetControllerInstance(requestContext, controllerType);
            }
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(String.Format("Error resolving controller {0}", controllerType.Name, ex));
        }

        return controller;
    }

Upvotes: 1

Adam Tuliper
Adam Tuliper

Reputation: 30152

There are several things you can try here:

routes.IgnoreRoute("{file}.css"); //plus others if you have specifics

or better yet just try

routes.RouteExistingFiles = false;

Upvotes: 0

Related Questions