MVC4 - 当优化设置为true时,Bundling不起作用

时间:2012-09-02 22:03:44

标签: c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-optimization

我想知道我在这里做的不正确。我正在使用ASP.NET C#MVC4,我想使用新的css / js优化功能。

这是我的HTML部分

@Styles.Render("~/content/css")

这是我的BunduleConfig.cs部分

bundles.Add(new StyleBundle("~/content/css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

// BundleTable.EnableOptimizations = true;

输出(有效):

<link href="/content/css/reset.css" rel="stylesheet"/>
<link href="/content/css/bla.css" rel="stylesheet"/>

然而,当我取消注释BundleTable.EnableOptimizations = true;时,html输出看起来像这样

<link href="/content/css?v=5LoJebKvQJIN-fKjKYCg_ccvmBC_LF91jBasIpwtUcY1" rel="stylesheet"/>

这当然是404.我不知道我做错了什么,请帮助,第一次使用MVC4。

6 个答案:

答案 0 :(得分:68)

我想问题是您将捆绑包放在实际存在的虚拟URL上,但它是一个目录。

MVC正在从您的捆绑包中创建一个虚拟文件,并从您指定的路径作为捆绑路径提供它。

该问题的正确解决方案是使用不直接映射到现有目录的捆绑路径,而是使用该目录中的虚拟文件名(也不映射到真实文件名)。

示例:

如果您的网站有一个名为/ content / css的文件夹,请按以下步骤制作您的css包:

在BundleConfig.cs中:

bundles.Add(new StyleBundle("~/content/css/AllMyCss.css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

在页面上:

@Styles.Render("~/content/css/AllMyCss.css")

请注意,这假设您的css文件夹中没有名为AllMyCss.css的文件。

答案 1 :(得分:26)

我不确定这是网络优化,还是WebGrease是如此挑剔,但其中一个(或两个)是你需要非常小心。

首先,您的代码没有任何问题:

bundles.Add(new StyleBundle("~/content/css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

事实上,这正是微软所做的。他们使用~/bundles用于css的主要原因是相对路径被搞砸了。考虑一下您的浏览器如何看待捆绑包 - 与查看任何其他URL的方式完全相同,并且所有与正常路径相关的规则仍然适用于相对路径。想象一下,你的css有../images/bullet.png的图像路径。如果您使用的是~/bundles,则浏览器会查找bundles上方的实际存在的目录。最终可能会在~/images中找到您可能在~/content/images中找到它的地方。

我发现了一些可以真正打破它并导致404错误的事情:

  • 仅供参考:我的目录结构为Content/CSS,其中包含CSS图像的images文件夹。
  • 我有EnableOptimizations=true强制在测试时使用捆绑包
  • 你要做的第一件事就是'查看来源',然后点击css链接查看它们是否正常工作

假设我们正在开发一个关于猫的网站。你可能有这个

 @Styles.Render("~/Content/css/cats.css")    // dont do this - see below why

 bundles.Add(new StyleBundle("~/content/css/cats.css").Include(
                    "~/content/css/reset.css",
                    "~/content/css/bla.css"));

这将在HTML中生成指向此路径的CSS链接:

/Content/css/cats.css?v=JMoJspikowDah2auGQBfQAWj1OShXxqAlXxhv_ZFVfQ1

但是这会产生404,因为我放了一个扩展名.css和IIS(我认为)感到困惑。

如果我将其更改为此,那么它可以正常工作:

 @Styles.Render("~/Content/css/cats")

 bundles.Add(new StyleBundle("~/content/css/cats").Include(
                    "~/content/css/reset.css",
                    "~/content/css/bla.css"));

其他人已经指出的另一个问题是你不能这样做

 @Styles.Render("~/Content/css")

如果您的css目录中有css目录或文件(不太可能有一个名为Content但没有扩展名的文件)。

另一个技巧是您需要确保生成的HTML具有版本号

<link href="/Content/css/cats?v=6GDW6wAXIN5DJCxVtIkkxLGpojoP-tBQiKgBTQMSlWw1" rel="stylesheet"/>

如果不是,看起来像这样,那么您可能没有与Bundle表和cshtml文件之间的包名称完全匹配。

<link href="/Content/css/cats" rel="stylesheet"/>

答案 2 :(得分:4)

不要忘记确保捆绑HttpModule就在那里。

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

这第一次刺痛了我。不确定是否应该通过NuGet包添加必要的配置,但这不是我的情况。

答案 3 :(得分:3)

这对我来说是正确的。启用优化后,您将只有一个引用,它将是您在StyleBundle(/ content / css)中指定的名称。在调试模式下(或者更具体地说,在web配置中使用debug = false),您将正常获得非优化文件。如果你看,你会发现它们只是在输入时只是纯文本。但是,当打开优化时(通常在发布模式下运行时),您将获得一个看起来很奇怪的URL。

如果你看一下它的输出会被缩小。查询字符串?v = 5KLoJ ....基于对包中文件的哈希。这样,只要您愿意,就可以安全地缓存HTTP缓存。永远,如果你喜欢,但我认为默认是一年。但是,如果您修改任何样式表,它将生成一个新的哈希值,并且“缓存破坏”,这样您就可以在浏览器上获得一个新的副本。

说了这么多,我不确定你为什么会得到404.我怀疑这与你的路由配置或你的IIS设置有关。您是否在使用IISExpress的Visual Studio中运行?

答案 4 :(得分:3)

我刚刚解决了类似的问题。问题如下,我通过NuGet安装了“选择”。 在BundleConfig类中,包含CSS文件的行如下所示:

bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css",)); 
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/chosen.css"));

在那个课堂上我有这条线的地方:

BundleTable.EnableOptimizations = true;

修复是将2 bundles.Add()合并为:

bundles.Add(new StyleBundle("~/Content/css").Include(
                            "~/Content/site.css", 
                            "~/Content/chosen.css"
                        ));

这为我解决了。

答案 5 :(得分:0)

也可能是因为您因某种原因未将bundleconfig.json部署到服务器。