It seems that ASP.NET MVC 3 will serve existing files first before looking at the routing table. This can be turned off by setting the option routes.RouteExistingFiles = true
. When it is set to not route existing files, it doesn't seem to serve all files. For example if a file is named *.cs it will not be served. If the file is renamed to .txt it will be served. I find this rather arbitrary and I haven't been able to find any documentation about what is served and what is not served. It should have been much better that static file serving was added as an entry in the routing table, with a StaticFileRouteHandler class or something along these lines. Does anyone have more information or details about this subject? I would like to have full control over what my application is serving or not.
P.S: I am using the ASP.NET development server.
For example if a file is named *.cs it will not be served
You may take a look at the <httpHandlers>
section of your c:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config
file. Mine looks like this:
<httpHandlers>
<add path="eurl.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" />
<add path="trace.axd" verb="*" type="System.Web.Handlers.TraceHandler" validate="True" />
<add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True" />
<add verb="*" path="*_AppService.axd" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False" />
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False"/>
<add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" />
<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />
<add path="*.asmx" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False" />
<add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
<add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False" />
<add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.master" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.skin" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.browser" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.sitemap" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.dll.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="True" />
<add path="*.exe.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="True" />
<add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.cs" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.csproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.vb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.vbproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.webinfo" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.licx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.resx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.resources" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.mdb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.vjsproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.java" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.jsl" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.ldb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.ad" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.dd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.ldd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.sd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.cd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.adprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.lddprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.sdm" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.sdmDocument" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.mdf" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.ldf" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.exclude" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.refresh" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
<add path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False"/>
<add path="*.rules" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
<add path="*.xoml" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False"/>
<add path="*.xamlx" verb="*" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="False"/>
<add path="*.aspq" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
<add path="*.cshtm" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
<add path="*.cshtml" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
<add path="*.vbhtm" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
<add path="*.vbhtml" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
<add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" />
<add path="*" verb="*" type="System.Web.HttpMethodNotAllowedHandler" validate="True" />
</httpHandlers>
So you can see all those forbidden extensions. They correspond to source code files and for security reasons are not served directly. Otherwise people would be able to look at your source code file.
If you wanted to serve them you could write a controller action which would serve those files.
I would like to say that IIS controls what files are served and that supersceed what the MVC Route table entries dictacte.
If you want to serve out .CS files you may need to adjust the MIME types in IIS.
Try adding a .cs extension mime type and make the file type text/cs.