简体   繁体   English

MVC4-优化设置为true时,捆绑不起作用

[英]MVC4 - Bundling does not work when optimizations are set to true

I wonder what I don't do correct here. 我想知道我在这里没有做正确的事情。 I am using ASP.NET C# MVC4 and I want to take use of new css/js optimization feature. 我正在使用ASP.NET C#MVC4,并且想使用新的CSS / JS优化功能。

Here is my HTML part 这是我的HTML部分

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

Here is my BunduleConfig.cs part 这是我的BunduleConfig.cs部分

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

// BundleTable.EnableOptimizations = true;

Output (works): 输出(工作):

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

However when I uncomment BundleTable.EnableOptimizations = true; 但是,当我取消注释BundleTable.EnableOptimizations = true; html output looks like this html输出看起来像这样

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

And this is, of course is 404. I have no idea where I did something wrong, please help, first time working with MVC4. 这当然是404。我不知道我在哪里做错了,请帮助,第一次使用MVC4。

I imagine the problem is you putting the bundle at a virtual URL that actually exists, but is a directory. 我想问题是您将捆绑软件放在实际存在的虚拟URL上,但是它是一个目录。

MVC is making a virtual file from your bundle and serving it up from the path you specify as the bundle path. MVC正在从您的捆绑包中创建一个虚拟文件,并从您指定为捆绑包路径的路径中提供该文件。

The correct solution for that problem is to use a bundle path that does not directly map to an existing directory, and instead uses a virtual file name (that also does not map to a real file name) inside that directory. 解决该问题的正确方法是使用一个不直接映射到现有目录的捆绑路径,而是在该目录内使用虚拟文件名(该虚拟文件名也未映射为真实文件名)。

Example: 例:

If your site has a folder named /content/css, make your css bundle as follows: 如果您的站点有一个名为/ content / css的文件夹,请按照以下步骤制作css捆绑包:

In BundleConfig.cs: 在BundleConfig.cs中:

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

And on the page: 并在页面上:

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

Note that this assumes you do NOT have a file named AllMyCss.css in your css folder. 请注意,这假设您的css文件夹中没有名为AllMyCss.css的文件。

I'm not sure if it's the web optimization, or WebGrease that is so picky but one (or both) of them is and you need to be extremely careful. 我不确定是Web优化还是WebGrease如此挑剔,但是其中之一(或两者兼有),您需要格外小心。

First of all there is nothing wrong with your code: 首先,您的代码没有错:

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

In fact this is exactly what Microsoft does. 实际上,这正是Microsoft所做的。 The main reason they don't use ~/bundles for css is that relative paths get screwed up for images. 他们为CSS使用~/bundles主要原因是相对路径弄乱了图像。 Think about how your browser sees a bundle - exactly the same way as it sees any other URL, and all the normal path related rules still apply with respect to relative paths. 想一想您的浏览器如何看到一个包-与看到任何其他URL的方式完全相同,并且所有与常规路径相关的规则仍然适用于相对路径。 Imagine your css had an image path to ../images/bullet.png . 假设您的CSS的图片路径为../images/bullet.png If you were using ~/bundles the browser would be looking in a directory above bundles which doesn't actually exist. 如果您使用的是~/bundles ,浏览器将在bundles上方的目录中查找,该目录实际上并不存在。 It will probably end up looking in ~/images where you probably have it in ~/content/images . 它可能最终会在~/images中查找,而在~/content/images可能包含它。

I've found a couple things that can really break it and cause 404 errors: 我发现了一些可以真正破坏它并导致404错误的东西:

  • FYI: My directory structure is Content/CSS which contains an images folder for CSS images. 仅供参考:我的目录结构是Content/CSS ,其中包含用于CSS图像的images文件夹。
  • I have EnableOptimizations=true to force use of bundles while testing 我有EnableOptimizations=true以在测试时强制使用包
  • First thing you should do is 'View Source' and just click on the css links to see if they work 您应该做的第一件事是“查看源代码”,然后单击css链接以查看它们是否有效

Let's say we're developing a site about cats. 假设我们正在开发一个有关猫的网站。 You may have this 你可能有这个

 @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"));

This generates a CSS link to this path in your HTML: 这将在您的HTML中生成指向此路径的CSS链接:

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

However this will give a 404 because I put an extension .css and IIS (I think) gets confused. 但是这会给出404,因为我把扩展名.css和IIS(我认为)混淆了。

If I change it to this then it works fine: 如果我将其更改为此,则可以正常工作:

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

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

Another problem already pointed out by others is you must not do 别人已经指出的另一个问题是你一定不能做

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

if you have a css directory or file (unlikely you'd have a file called css with no extension) in your Content directory. 如果您的Content目录中有一个css目录或文件(不太可能有一个没有扩展名的css文件)。

An additional trick is that you need to make sure your generated HTML has a version number 另一个技巧是,您需要确保生成的HTML具有版本号

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

If it doesn't and looks like this, then you probably don't have an exact match for the bundle name between your Bundle table and in your cshtml file. 如果没有,并且看起来像这样,那么您的Bundle表和cshtml文件中的bundle名称可能不完全匹配。

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

Don't forget to ensure the bundling HttpModule is there. 不要忘了确保捆绑的HttpModule在那里。

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

This stung me first time around. 这让我很头疼。 Not sure if the necessary config should be added by the NuGet package, but it wasn't in my case. 不知道NuGet程序包是否应该添加必要的配置,但是在我看来并不是这样。

That looks correct to me. 在我看来,这是正确的。 When optimizations are enabled you'll only have a single ref and it'll be for the name you specified in your StyleBundle (/content/css). 启用优化后,您将只有一个引用,并且将使用您在StyleBundle(/ content / css)中指定的名称。 In debug mode (or more specifically with debug=false in your web config) you'll get the non-optimized files as normal. 在调试模式下(或更具体地说,在Web配置中使用debug = false),您将像往常一样获得未优化的文件。 If you look, you'll see they're just plain text as you typed them. 如果您看的话,您会看到它们只是您键入时的纯文本。 However, when optimzations are turned on (usually when you run in release mode) you'll get a wierd looking URL instead. 但是,启用优化功能后(通常在发布模式下运行),您会得到一个看起来更加古怪的URL。

If you look at the output of that it'll be minified. 如果您看一下它的输出,它将被缩小。 The Query string ?v=5KLoJ.... is based on a hash taken of the files in the bundle. 查询字符串?v = 5KLoJ ....是基于捆绑中文件的哈希值。 This is so that the reference can be safely HTTP cached for as long as you want. 这样一来,只要您愿意,就可以安全地对HTTP引用进行高速缓存。 Forever if you fancy, but I think the default is a year. 如果您愿意,可以永远,但我认为默认值为一年。 However, if you modify any of your stylesheets it will generate a new hash and that's "cache-busting" so you'll get a fresh copy on the browser. 但是,如果您修改任何样式表,它将生成一个新的哈希,并且该哈希是“缓存无效的”,因此您将在浏览器上获得一个全新的副本。

Having said all that, I'm not sure why you're getting a 404. I suspect that has something to do with your routing configuration or your IIS setup. 说了这么多,我不确定为什么会收到404。我怀疑这与您的路由配置或IIS设置有关。 Are you running in Visual Studio with IISExpress? 您是否正在使用IISExpress在Visual Studio中运行?

I just resolved a similar problem. 我刚刚解决了类似的问题。 The problem was as follow, i installed 'chosen' via NuGet . 问题如下,我通过NuGet安装了“选择”。 And in the BundleConfig class, the line that included the CSS file looked like this: BundleConfig类中,包含CSS文件的行如下所示:

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

Some where down in that class i had this line: 在该班级的某些地方,我有这条线:

BundleTable.EnableOptimizations = true;

The fix was to combine the 2 bundles.Add() like so: 解决方法是将2个bundles.Add()合并为:

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

And that fixed it for me. 这为我解决了。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM