C# 为什么CSS和JS文件绕过Asp.NETMVC路由?

C# 为什么CSS和JS文件绕过Asp.NETMVC路由?,c#,asp.net,asp.net-mvc,asp.net-mvc-4,asp.net-mvc-routing,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Asp.net Mvc Routing,我收到了一个用Asp.NETMVC4构建的原型应用程序。它目前正在使用NInject、ServiceLocator和all将默认控制器工厂替换为自定义工厂 问题在于,通过替换默认控制器工厂,对JS文件的请求被视为对控制器和操作的合法请求 因此,查看Visual Studio创建的默认模板,路由配置如下所示: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.

我收到了一个用Asp.NETMVC4构建的原型应用程序。它目前正在使用NInject、ServiceLocator和all将默认控制器工厂替换为自定义工厂

问题在于,通过替换默认控制器工厂,对JS文件的请求被视为对控制器和操作的合法请求

因此,查看Visual Studio创建的默认模板,路由配置如下所示:

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 }
    );
}
看了之后,我问自己:为什么对“/Scripts/jquery.js”的请求不会被Asp.NETMVC解释?我的意思是,为什么它不认为“Script”是一个控制器,“jquery.js”是一个动作

因为如果我禁用控制器工厂覆盖,项目就会工作,所以我只能假设默认工厂负责此类检查。这意味着“/Scripts/jquery.js”确实会被传递到控制器工厂,这是我不知道的

有人能解释一下吗


重写控制器工厂时应该做什么样的处理以避免此类问题?

这不是因为MVC如何处理对jquery.js的请求,而是因为IIS处理对jquery.js的请求的方式。IIS假定.js、.jpg等资源都是静态资源,因此不需要通过ASP.NET引擎传递它们。为了防止这种情况发生,您可以在web.config中添加一行,以获取您希望IIS保留的路径

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


添加类似的内容应该允许您的JS文件通过ASP.NET提供服务,而不是直接通过IIS提供服务。

经过进一步的研究,我发现以下引用自Steven Sanderson的书:

但是,路由系统仍然会检查文件系统,查看传入的URL是否与文件或磁盘匹配,如果匹配,路由将忽略该请求(绕过URL可能也匹配的任何路由条目),以便直接提供文件。这对于静态文件非常方便,例如图像、CSS和JavaScript文件。您可以将它们保留在项目中(例如,在/Content或/Script文件夹中),然后直接引用和提供它们,就像您根本不使用路由一样。由于文件确实存在于磁盘上,因此优先于路由配置

相反,如果希望路由配置优先于磁盘上的文件,可以将RouteCollection的RouteExistingFiles属性设置为true。(默认情况下为false。)

这是一件非常有趣的事情,让我想到了真正的问题。一个简单得多的。碰巧,文件夹中不存在相关脚本。至少不是视图上请求的版本完全相同的版本。这就是Asp.NETMVC认为这是控制器/操作请求的原因


参考资料:

+1,感谢您提醒我web.config的处理程序部分及其设置方式。我找到了解决我问题的办法。检查我的答案。再次感谢你的帮助,没问题。前几天我遇到了几乎完全相同的问题。我已经完全忘记了如何处理文件。可能要将
RouteExistingFiles
设置为true并添加这一行