Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 971
Rodrigo Lira Avatar asked Jun 05 '13 20:06

Rodrigo Lira


2 Answers

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.

like image 172
ThaBigGuy Avatar answered Sep 29 '22 06:09

ThaBigGuy


After a little bit more of research I found the following quote from Steven Sanderson's book:

However, the routing system still does check the file system to see if an incoming URL happens to match a file or disk, and if so, routing ignores the request (bypassing any route entries that the URL might also match) so that the file will be served directly. This is very convenient for static files, such as images, CSS, and JavaScript files. You can keep them in your project (e.g., in your /Content or /Script folders), and then reference and serve them directly, just as if you were not using routing at all. Since the file genuinely exists on disk, that takes priority over your routing configuration.

If, instead, you want your routing configuration to take priority over files on disk, you can set the RouteCollection’s RouteExistingFiles property to true. (It’s false by default.)

That was something very interesting to learn and led me to the actual problem. A much simpler one. As it happened, the pertinent scripts were not present on the folder. At least not the ones with the exact same version requested on the view. That was the responsible for Asp.Net MVC thinking it was a controller/action request.

Reference: http://forums.asp.net/t/1536510.aspx/1

like image 23
Rodrigo Lira Avatar answered Sep 29 '22 07:09

Rodrigo Lira