最近在使用 MVC 开发的时候,遇到一个对我来说“奇怪的问题”,就是使用 BundleTable 进行 CSS、JS 文件绑定,然后使用 Styles.Render、Scripts.Render 进行获取,但总是获取不到绑定的 CSS、JS 文件,然后报“404错误”,话说再多,不如一个代码示例。

BundleConfig 配置代码:

public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/test.js").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));
bundles.Add(new StyleBundle("~/bundles/test.css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
}
}

视图获取:

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/bundles/test.css")
@Scripts.Render("~/bundles/test.js")
</head>

这个问题我相信大家应该都遇到过,当然前提条件是按照我上面那种写法,问题出来了,那该如何解决呢?因为你不知道问题出在哪,所以只能进行反复的尝试,最后我无意间把 .css 和 .js 后缀去掉就可以了,在上一个开发项目我就是这么干的,然后现在开发的项目又遇到这个问题,这就引起了我的重视,当然这不是一个解决方法,只是你不知道它背后的东西罢了。

小标签:当使用 VS 调试模式时,即 web.config 中 debug="true",使用 BundleConfig.RegisterBundles 进行注册是没有效果的,但是可以展示,只不过没有起到“绑定”文件的作用,解决方式是,需要手动在 Application_Start 代码中添加:BundleTable.EnableOptimizations = true;

除了把 .css 和 .js 后缀去掉,网上搜索,还有一种解决方法就是,在 web.config 添加如下配置:

  <system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</modules>
</system.webServer>

runAllManagedModulesForAllRequests 这个东西,之前我也遇到过,但不是像这次使用 Styles.Render、Scripts.Render 引起的,而是使用 MapRoute 进行 .htm 文件路由配置的时候,出现“404”错误,然后在 web.config 添加上面的配置就可以了,我还纪录了一篇博文: 【记录】ASP.NET MVC MapRoute .htm 不起作用 ,哎,当时并没有深入进行研究 runAllManagedModulesForAllRequests,只是认为既然能解决问题就行了,现在一想,其实心里有点后怕,为什么这样说?看下面就知道了。

runAllManagedModulesForAllRequests 到底是什么东西呢?其实从它名字上面,你就可以明白一点,这也就是命名好的好处啊,咳咳,说白了,其意思就是为所有 Modules 管理请求的一个开关,如果设置为 true,就是把 所有请求 到 Modules 的通道打通了,没有任何阻拦,那 Modules 又是什么呢?字面意思可以理解为“模块”或“单元”的意思,它是属于 Web 服务器的东西,和 Web 应用程序不太相关,Web 应用程序只是对它发起一个请求,Modules 的相关东西,可以看下这一篇非常好的文章: IIS Modules Overview 。

使用 IIS 部署站点的时候,在点击站点,右侧会有一个“主页”,我们会看到 Modules 的“身影”:

点击“模块”,就可以看到 IIS 所有的默认 Modules:

所有 Module 的具体说明可以查看: Module Reference ,我们看一个等会我们要用到的 Module-StaticFileModule(静态文件管理模块):

  • Description: Sends out static files with the file extension .html, .jpg, as well as many others. The staticContent/mimeMap configuration collection determines the list of file extensions.
  • Configuration sections: system.webServer/staticContent
  • Dependencies: None.
  • Potential issues when removing this module: Static files no longer become served. Requests for files return a 404 Not Found error indicating that no handler was matched.

上面说到,使用 MapRoute 进行 .htm 文件路由配置,出现“404错误”,我原本是想通过配置 StaticFileModule 进行解决,试过之后发现不行,staticContent/mimeMap 配置中,IIS 默认是有 .htm 配置的,具体为: <mimeMap fileExtension=".htm" mimeType="text/html"/> ,详细博文介绍: IIS 6中mimemap属性的默认设置 ,而且最重要的是 StaticFileModule 是管理所有静态文件请求的,其实 MapRoute 进行 .htm 文件路由配置的请求,是到不了 StaticFileModule 模块处理的,要不然早就可以访问了,URL 路由配置有一个单独的模块-UrlMappingsModule,这部分内容后面再了解。

至于 Styles.Render、Scripts.Render 获取包含后缀绑定的“404错误”,可以用下面配置进行解决:

  <system.webServer>
<modules>
<add name="BundleModule" type="System.Web.Optimization.BundleModule" />
</modules>
</system.webServer>

其实上面这两个问题的“另类”解决方式,归根到底就是想避免使用 runAllManagedModulesForAllRequests="true" ,为什么要避免使用它?当然是有原因的,在说这个之前,再来看一个有意思的问题,可能和这个不太相关,但我还是想说一下。

先来看一段 web.config 配置:

<configuration>
<system.web>
<authentication mode="Forms">
<forms name="MembershipCookie"
loginUrl="Login.aspx"
protection="All"
timeout="525600"
slidingExpiration="true"
enableCrossAppRedirects="true"
path="/" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<location path="Default.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
</configuration>

这段代码表示什么意思呢?authorization 配置的用户访问类型为“普通用户授权后才能访问”,location/authorization 是对某一页面进行身份验证,针对 Default.aspx 的身份验证类型为“匿名可访问”,并且 Default.aspx 为此站点的默认访问文档,可以理解为此站点出了 Default.aspx,其他页面访问都是需要身份验证的,然后跳转到 Login.aspx。

运行后,你会发现其实并不是这么回事,比如访问 www.mysite.com,按照配置应该会访问 www.mysite.com/Default.aspx,但是你会发现,它会跳转到 www.mysite.com/Login.aspx,为什么会这样呢?其实是 IIS 版本更新的问题,Stack Overflow 中详细的问题描述: ASP.NET 2.0 and 4.0 seem to treat the root url differently in Forms Authentication ,在他问题描述中,尝试用 UrlRewriter,但是还是没有起到效果,最后做了一个测试:

ASP.NET Version  Url                                 Behaviour
-------------------------------------------------------------------------
2.0 http://example.com Renders Default.aspx
2.0 http://example.com/Default.aspx Renders Default.aspx
4.0 http://example.com Redirects to Login.aspx
4.0 http://example.com/Default.aspx Renders Default.aspx

相关的两篇 IIS 更新说明:

第一篇博文主要是说明 IIS 的一个更新,具体内容可以简化为:After this patch is applied, ASP.NET 4 applications can handle requests for extensionless URLs. Therefore, managed HttpModules that run prior to handler execution will run. 什么意思?就是处理程序增加了一个"*"的映射,也就是说,比如文中提到的,更新之前只能访问如下 URL:www.example.com/ExampleSite/ExampleFile.,注意后面是有“点”的,也就是只能访问有扩展名的 URL,更新之后,可以访问无扩展名的 URL,也就是可以把那个“点”去掉,这样蕴含什么意思呢?注意上面英文的后面一句话,这句话就说明了后面那篇博文的问题原因。

后面一篇博文主要也是说明,上面 Stack Overflow 中所描述的那个问题,比如我访问 www.mysite.com,更新之前,会根据配置文件中的“默认文档”,找到相关页面后,再根据 web.config 中的身份验证配置,进行处理并显示,如果按照上面的 web.config 配置,访问的是 www.mysite.com/Default.aspx(匿名用户),但是更新后,IIS 就可以处理 无扩展名 的 URL,得到响应的 URL 后,会立马交给 Modules 进行处理,首先就是 UrlAuthentication、FromsAuthentication 模块进行身份验证处理,发现是“非法用户”,然后就跳转到了 www.mysite.com/Login.aspx,而直接访问 www.mysite.com/Default.aspx,会先走配置文件的 location 身份验证说明,因为更新针对的是“无扩展名”的 URL,而 www.mysite.com/Default.aspx 是有扩展名的 URL,说了那么多,微软最后给出的解决方案是:

<configuration>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrl-Integrated-4.0" />
<remove name="ExtensionlessUrl-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrl-ISAPI-4.0_32bit" />
</handlers>
</system.webServer>
</configuration>

其实这个问题和 runAllManagedModulesForAllRequests 不太相关,但它可以带你思考 URL 和 Modules 之间的“微妙关系”,至于为什么避免使用 runAllManagedModulesForAllRequests="true" ,我贴出两篇博文:

这篇博文就到这,后面解决一下不配置 runAllManagedModulesForAllRequests="true" ,使用 MapRoute 进行 .htm 文件路由配置,出现的“404错误”。

<modules runAllManagedModulesForAllRequests="true" />(转1)的更多相关文章

  1. 塞翁失马,焉知非福:由 Styles.Render 所引发 runAllManagedModulesForAllRequests="true" 的思考

    最近在使用 MVC 开发的时候,遇到一个对我来说"奇怪的问题",就是使用 BundleTable 进行 CSS.JS 文件绑定,然后使用 Styles.Render.Scripts ...

  2. 【续集】塞翁失马,焉知非福:由 Styles.Render 所引发 runAllManagedModulesForAllRequests="true" 的思考

    在上一篇中,还有个遗留问题没有解决,就是 ASP.NET MVC MapRoute .htm 不起作用,如果不使用 runAllManagedModulesForAllRequests="t ...

  3. 不要随便使用 runAllManagedModulesForAllRequests="true" 来解决问题

    在 IIS 7.0 中,对于使用 Url 路由 访问页面的 ASP.NET 应用程序,IIS可能会不能出 Url 是对 ASP.NET 的请求. 会显示404啊,403啊之类的错误代码(因为路径不存在 ...

  4. runAllManagedModulesForAllRequests 和 invalid url

    有这样的经验, 在本地的 IIS 上网站运行正常,但是发布到服务器上就一堆怪怪的问题 : MVC routing not work http://stackoverflow.com/questions ...

  5. IIS部署ASP.NET网站后提示只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态...

    今天,在IIS上部署网站后,出现了下面错误: 只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态.还请确保在应用程序配置的 <sy ...

  6. IIS Modules Overview

    Introduction The IIS 7 and above Web server feature set is componentized into more than thirty indep ...

  7. 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用

    由于ASP.NET Web API具有与ASP.NET MVC类似的编程方式,再加上目前市面上专门介绍ASP.NET Web API 的书籍少之又少(我们看到的相关内容往往是某本介绍ASP.NET M ...

  8. Win10 IIS本地部署MVC网站时不能运行?

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 部署后出现这个错误: 打开文件目录后发现是可以看见目录的,静态页面也是可以打开的 ...

  9. MVC通过路由实现URL重写

    public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Ro ...

随机推荐

  1. OWIN初探(转)

    什么是 OWIN ? OWIN 的全称是 "Open Web Interface for .NET", OWIN 在 .NET Web 服务器和 .NET Web 应用之间定义了一 ...

  2. redis的5种数据结构的简介

    5种数据结构 1.字符串 Redis 字符串是一个字节序列.在 Redis 中字符串是二进制安全的,这意味着它们没有任何特殊终端字符来确定长度,所以可以存储任何长度为 512 兆的字符串. 示例 12 ...

  3. respondsToSelector的使用

    - (BOOL)respondsToSelector:(SEL)aSelector; 用来判断是否有以某个名字命名的方法 +(BOOL) instancesRespondToSelector: sel ...

  4. Symfony2 Doctrine从现有Database生成Entity(转载自http://blog.it985.com/6809.html)

    在我的以前一章Symfony之十分钟入门说了怎样生成数据库,然后设计实体Entity,再同步数据库的表结构,一般我们的顺序都是这样:生成数据库->设计实体Entity->同步数据库表结构. ...

  5. CoreData (四)备

    监听NSFetchedResultsController 之前说过, NSFetchedResultsController是有两个重要的功能. 第一:NSFetchedResultsControlle ...

  6. 树状数组(BIT)

    i的二进制的最后一个1可以通过i&(-i)得到,时间复杂度o(logn).对于W*H的二维BIT只需要建立H个大小为x轴方向元素个数W的BIT,复杂度O(logW+logH).同样的方法可以扩 ...

  7. Google Chrome源码剖析【序】

    [序(本人什么都没做,完全转载)] 开源是口好东西,它让这个充斥着大量工业垃圾代码和教材玩具代码的行业,多了一些艺术气息和美的潜质.它使得每个人,无论你来自米国纽约还是中国铁岭,都有机会站在巨人的肩膀 ...

  8. ftp二进制与ascii传输方式区别

    ASCII 和BINARY模式区别:    用HTML 和文本编写的文件必须用ASCII模式上传,用BINARY模式上传会破坏文件,导致文件执行出错.    BINARY模式用来传送可执行文件,压缩文 ...

  9. ubuntu 执行apt-get update 提示无法获得锁

    问题如下: y@y:~$ sudo apt-get updateE: 无法获得锁 /var/lib/apt/lists/lock - open (11: 资源暂时不可用)E: 无法对目录 /var/l ...

  10. BZOJ 1877 晨跑

    http://www.lydsy.com/JudgeOnline/problem.php?id=1877 思路:拆点费用流,答案就是最大流量和最小费用. #include<algorithm&g ...