MVC4 StyleBundle不会呈现正确的顺序包 [英] MVC4 StyleBundle doesn't render the bundle in the correct order
问题描述
我想呈现的css文件捆绑,但输出是错误的顺序。我试着解决@ <一个href=\"http://stackoverflow.com/questions/9657412/mvc4-beta-minification-and-bundling-ordering-files-and-debugging-in-browser\">MVC4贝塔缩小与绑扎:订购文件和调试中的浏览器,但它并没有帮助。这里是束:
I'm trying to render a bundle of css files, but the output is in wrong order. I've tried the solution @ MVC4 Beta Minification and Bundling: Ordering files and debugging in browser , but it didn't help. Here is the bundle:
bundles.Add(new StyleBundle("~/stylesheet")
.Include("~/css/main.css")
.Include("~/css/mvc.css")
.Include("~/js/jquery.thickbox.css")
.Include("~/js/jquery.rating.css")
.Include("~/css/ProductListing.css")
.Include("~/css/dropdown/dropdown.css")
.Include("~/css/dropdown/dropdown.vertical.css")
.Include("~/js/fancybox/jquery.fancybox-1.3.1.css")
.Include("~/css/scartpopup.css")
.Include("~/css/ShoppingCart.css")
.Include("~/css/ceebox.css")
.Include("~/css/tooltip.css")
.Include("~/css/recent_blog_posts.css")
.Include("~/css/ProductDetail.css")
.Include("~/css/jquery-ui-1.7.3.custom.css")
.Include("~/css/filter_box.css")
.Include("~/css/custom_page.css")
.Include("~/css/Checkout.css")
.Include("~/css/CheckoutButton.css")
);
这是结果,你可以看到了jQuery的UI来顶。
And here is the result, as you can see the jquery-ui comes to top.
<link href="/css/jquery-ui-1.7.3.custom.css" rel="stylesheet"/>
<link href="/css/main.css" rel="stylesheet"/>
<link href="/css/mvc.css" rel="stylesheet"/>
<link href="/js/jquery.thickbox.css" rel="stylesheet"/>
<link href="/js/jquery.rating.css" rel="stylesheet"/>
<link href="/css/ProductListing.css" rel="stylesheet"/>
<link href="/css/dropdown/dropdown.css" rel="stylesheet"/>
<link href="/css/dropdown/dropdown.vertical.css" rel="stylesheet"/>
<link href="/js/fancybox/jquery.fancybox-1.3.1.css" rel="stylesheet"/>
<link href="/css/scartpopup.css" rel="stylesheet"/>
<link href="/css/ShoppingCart.css" rel="stylesheet"/>
<link href="/css/ceebox.css" rel="stylesheet"/>
<link href="/css/tooltip.css" rel="stylesheet"/>
<link href="/css/recent_blog_posts.css" rel="stylesheet"/>
<link href="/css/ProductDetail.css" rel="stylesheet"/>
<link href="/css/filter_box.css" rel="stylesheet"/>
<link href="/css/custom_page.css" rel="stylesheet"/>
<link href="/css/Checkout.css" rel="stylesheet"/>
<link href="/css/CheckoutButton.css" rel="stylesheet"/>
我怎样才能确保样式表以正确的顺序呈现?
How can I make sure that the stylesheets are rendered in correct order?
推荐答案
不应该捆绑呈现在完全相同的顺序CSS文件,它遵循不同的逻辑。如果你需要使它们的定义,那么你应该创建一个自定义的<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.optimization.ibundleorderer.aspx\">IBundleOrderer并将其设置为束作为所需订户
Bundling is not supposed to render the CSS files in the exact same order, it follows a different logic. If you need to render them as defined, then you should create a custom IBundleOrderer and set it to the bundle as the required Orderer:
public class AsDefinedBundleOrderer : IBundleOrderer
{
public IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
{
return files;
}
}
和
var bundle = new StyleBundle("~/stylesheet");
bundle.Orderer = new AsDefinedBundleOrderer();
bundles.Add(bundle);
那么这将什么也不做的列表,以便将渲染正好使它们以相同的顺序。
Then this will do nothing with the list so Render will render them exactly in the same order.
这是默认的排序的更新
捆绑使用 IBundleOrderer
的理念,以捆绑
中的项目进行排序。
在捆绑
类都有它看起来像这样订货人
属性:
Bundling uses the concept of IBundleOrderer
to sort the items within a Bundle
.
The Bundle
class has it's Orderer
property which looks like this:
public IBundleOrderer Orderer
{
get
{
if (this._orderer == null)
return (IBundleOrderer) DefaultBundleOrderer.Instance;
else
return this._orderer;
}
set
{
this._orderer = value;
this.InvalidateCacheEntries();
}
}
所以默认订货人实际上是一个 DefaultBundleOrderer
,直到你与你的自定义订购者覆盖。
So the default orderer is actually a DefaultBundleOrderer
until you overwrite it with your custom orderer.
的 IBundleOrderer
具有以下签名:
public interface IBundleOrderer
{
IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files);
}
的 DefaultBundleOrderer
执行此订单减少文件的的BundleContext
,这里是从执行一个片段 OrderFiles
:
The DefaultBundleOrderer
implementation of this orders the files by the BundleContext
, here is a snippet from the implementation of OrderFiles
:
foreach (BundleFileSetOrdering ordering in (IEnumerable<BundleFileSetOrdering>) context.BundleCollection.FileSetOrderList)
DefaultBundleOrderer.AddOrderingFiles(ordering, (IEnumerable<FileInfo>) list, fileMap, foundFiles, result);
因此,不同的结果发生,因为这一点。这当然不是一个随机排序算法的:)
这些规则在 BUndleCollection
类中定义的:
public static void AddDefaultFileOrderings(IList<BundleFileSetOrdering> list)
{
if (list == null)
throw new ArgumentNullException("list");
BundleFileSetOrdering bundleFileSetOrdering1 = new BundleFileSetOrdering("css");
bundleFileSetOrdering1.Files.Add("reset.css");
bundleFileSetOrdering1.Files.Add("normalize.css");
list.Add(bundleFileSetOrdering1);
BundleFileSetOrdering bundleFileSetOrdering2 = new BundleFileSetOrdering("jquery");
bundleFileSetOrdering2.Files.Add("jquery.js");
bundleFileSetOrdering2.Files.Add("jquery-min.js");
bundleFileSetOrdering2.Files.Add("jquery-*");
bundleFileSetOrdering2.Files.Add("jquery-ui*");
bundleFileSetOrdering2.Files.Add("jquery.ui*");
bundleFileSetOrdering2.Files.Add("jquery.unobtrusive*");
bundleFileSetOrdering2.Files.Add("jquery.validate*");
list.Add(bundleFileSetOrdering2);
BundleFileSetOrdering bundleFileSetOrdering3 = new BundleFileSetOrdering("modernizr");
bundleFileSetOrdering3.Files.Add("modernizr-*");
list.Add(bundleFileSetOrdering3);
BundleFileSetOrdering bundleFileSetOrdering4 = new BundleFileSetOrdering("dojo");
bundleFileSetOrdering4.Files.Add("dojo.*");
list.Add(bundleFileSetOrdering4);
BundleFileSetOrdering bundleFileSetOrdering5 = new BundleFileSetOrdering("moo");
bundleFileSetOrdering5.Files.Add("mootools-core*");
bundleFileSetOrdering5.Files.Add("mootools-*");
list.Add(bundleFileSetOrdering5);
BundleFileSetOrdering bundleFileSetOrdering6 = new BundleFileSetOrdering("prototype");
bundleFileSetOrdering6.Files.Add("prototype.js");
bundleFileSetOrdering6.Files.Add("prototype-*");
bundleFileSetOrdering6.Files.Add("scriptaculous-*");
list.Add(bundleFileSetOrdering6);
BundleFileSetOrdering bundleFileSetOrdering7 = new BundleFileSetOrdering("ext");
bundleFileSetOrdering7.Files.Add("ext.js");
bundleFileSetOrdering7.Files.Add("ext-*");
list.Add(bundleFileSetOrdering7);
}
所以,当你调用这个的Application_Start
:
BundleConfig.RegisterBundles(BundleTable.Bundles);
其实你通过默认的 BundleCollection
在库中定义的。
因此,我们必须通过一个接一个到 BundleFileSetOrdering
实例:
So we have the BundleFileSetOrdering
instances passed one-by-one into:
private static void AddOrderingFiles(BundleFileSetOrdering ordering, IEnumerable<FileInfo> files, Dictionary<string, HashSet<FileInfo>> fileMap, HashSet<FileInfo> foundFiles, List<FileInfo> result)
{
foreach (string key in (IEnumerable<string>) ordering.Files)
{
if (key.EndsWith("*", StringComparison.OrdinalIgnoreCase))
{
string str = key.Substring(0, key.Length - 1);
foreach (FileInfo fileInfo in files)
{
if (!foundFiles.Contains(fileInfo) && fileInfo.Name.StartsWith(str, StringComparison.OrdinalIgnoreCase))
{
result.Add(fileInfo);
foundFiles.Add(fileInfo);
}
}
}
else if (fileMap.ContainsKey(key))
{
List<FileInfo> list = new List<FileInfo>((IEnumerable<FileInfo>) fileMap[key]);
list.Sort((IComparer<FileInfo>) FileInfoComparer.Instance);
foreach (FileInfo fileInfo in list)
{
if (!foundFiles.Contains(fileInfo))
{
result.Add(fileInfo);
foundFiles.Add(fileInfo);
}
}
}
}
}
结论
如果我们想要简化这个过程,我们可以说,库prefers某些类型的文件,并就其他文件的一些排序,如果发现多种可能性。这是预期的行为的大部分时间,但你可以看到它是用 AsDefinedBundleOrderer
所以它什么都不设置指定的文件,因此为了保持原来的伊斯利重写。
If we want to simplify the process we can say that the library prefers some kind of files and makes some sorting on the other files if multiple possibilities found. This is the expected behavior most of the time but as you can see it is easly overridable with the AsDefinedBundleOrderer
so it does nothing with the given file set so the order remains the original.
这篇关于MVC4 StyleBundle不会呈现正确的顺序包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!