【问题标题】:MVC4 - Bundling does not work when optimizations are set to trueMVC4 - 当优化设置为 true 时捆绑不起作用
【发布时间】:2012-08-27 17:35:03
【问题描述】:

我想知道我在这里做的不对。我正在使用 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。

【问题讨论】:

  • 如果您创建 EnableOptimizations=true 倾向于查找的 ~content/css/reset.min.css 和 bla.min.css 文件会发生什么?
  • 我刚刚创建了一个空项目并尝试了两个css 文件,同样的事情发生了。也许是因为我将我的 css 文件放在 /content/css/ 文件夹中,而不仅仅是 /content/ 但我对此表示怀疑......

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


【解决方案1】:

也可能是因为某些原因你没有将 bundleconfig.json 部署到服务器上。

【讨论】:

    【解决方案2】:

    我想问题是您将捆绑包放在实际存在的虚拟 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 的文件。

    【讨论】:

    • 不会将包放在不存在的目录中导致 CSS 中的相对引用出现问题吗? devwhib.blogspot.com/2012/08/…
    • 解决相对引用问题的方法很多。如果您的 css 中有相对引用,请将它们转换为绝对引用,将资源嵌入 css,将相对引用视为 css 文件本身位于虚拟 url,或者使虚拟 url 与实际文件位置。
    • 完全按照你所说的@dodexahedron,但仍然无法正常工作:(在浏览器控制台中为该网址获取 404 错误:localhost:60676/Content/css/…
    【解决方案3】:

    我不确定是 Web 优化还是 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")
    

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

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

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

    如果不是并且看起来像这样,那么您的 Bundle 表和 cshtml 文件中的包名称可能不完全匹配。

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

    【讨论】:

    • 我不确定我是否误读了这里,但您似乎在建议 new StyleBundle("~/content/css") 很好并且推荐,但如果您有 @987654340 也不好content 目录中的 @ 文件夹(这是一个非常标准的设置)。
    • @MattMitchell 实际上这就是 OP 所说的,所以我解释了为什么它会导致错误以及为什么你不应该这样命名它。
    【解决方案4】:

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

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

    这是第一次让我感到刺痛。不确定 NuGet 包是否应该添加必要的配置,但在我的情况下不是。

    【讨论】:

      【解决方案5】:

      我刚刚解决了一个类似的问题。问题如下,我通过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"
                              ));
      

      这为我解决了问题。

      【讨论】:

        【解决方案6】:

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

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

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

        【讨论】:

        • 我正在使用 ASP.NET 开发服务器(集成一个用于测试/调试)运行 VS2010。
        • 你在调用 EnableDefaultBundles() 吗?否则,听起来您的 URL 没有通过 - 尝试将应用程序池的模式更改为“集成”。
        猜你喜欢
        • 2013-10-27
        • 2016-03-14
        • 1970-01-01
        • 2013-01-14
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        • 2017-01-23
        相关资源
        最近更新 更多