Why CSS and JS files bypass Asp.Net MVC routes?

Rodrigo Lira picture Rodrigo Lira · Jun 5, 2013 · Viewed 14.9k times · Source

I received a prototype application built with Asp.Net MVC4. It is currently replacing the default controller factory with a custom one using NInject, ServiceLocator and all.

The problem is that by replacing the default controller factory, the requests to JS files are being treated as if it was a legit request for a controller and an action.

So, looking at the default template create by Visual Studio, route configuration looks like this:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id =   UrlParameter.Optional }
    );
}

After looking that, I'm asking myself: How come a request to "/Scripts/jquery.js" does not get interpreted by Asp.Net MVC? I mean, why doesn't it think "Script" is a controller and "jquery.js" is an action?

Because the project works if I disable the controller factory override, I can only assume that the default factory is the responsible for that kind of check. And that would mean that a "/Scripts/jquery.js" are indeed passed to the controller factory which is something I didn't really know.

Could anyone shed some light on that?

What kind of treatment should one do when overriding the controller factory to avoid such problems?

Answer

ThaBigGuy picture ThaBigGuy · Jun 5, 2013

It's not because of how MVC handles the request to jquery.js it's because of the way IIS handles the request to jquery.js. IIS assumes that resources such as .js, .jpg, etc, are all static resources, and thus doesn't need to pass them through the ASP.NET engine. In order to to prevent this from occurring you can add a line to the web.config for a path that you want IIS to leave alone.

<system.webserver>
    <handlers>
    <add name="scripts" path="/Scripts/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
    </handlers>
</system.webserver>

Adding something like that should allow your JS files to be served via ASP.NET and not directly through IIS.