ASP.NET MVC-捆绑配置顺序


84

我正在尝试在ASP.NET MVC 5应用程序中使用特定的语言环境(es-CL)。我有以下内容:

  1. 将web.config uiculture和区域性更改为“ es-CL”
  2. 安装了GlobalizejQuery.Validation.Globalize
  3. 更改了我视图中的默认语言: <html lang="es-cl">
  4. 创建了一个新的捆绑包,并将其包含在适当的视图中。

BundleConfig.cs中

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
    .Include("~/Scripts/jquery.validate.js")
    .Include("~/Scripts/jquery.validate.unobtrusive.js"));

bundles.Add(new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js"));

在适当的视图中:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/globalization")
}

但是,生成的源代码如下:

<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

<script src="/Scripts/jquery.validate.globalize.js"></script>
<script src="/Scripts/globalize/globalize.js"></script>
<script src="/Scripts/globalize/cultures/globalize.culture.es-CL.js"></script>

请注意,jquery.validate.globalize.js脚本是在globalize.js之前加载的,这不是我想要的。

为什么会这样呢?是否可以依靠单个包中的包含顺序,还是我被迫将此单个脚本放在另一个包中并在我的视图中指定它?



@PaulMcCowat是的,但是我还没有使用缩小版本。我正在使用Microsoft.AspNet.Web.Optimizations 1.1.0。
莱昂纳多·埃雷拉,

@LeonardoHerrera我想就像克里斯在他的评论中提到的那样,已知文件被移动到捆绑器指定的顺序...但是我不确定,因为我不知道这些文件是什么,这导致我问。我很想知道是否使用IBundleOrderer对您有效,因为指定订单无效。
MikeSmithDev 2013年

看看[此链接] @Softlion答案[1] [1]:stackoverflow.com/questions/11979718/...
奥米德-RH

@section Scripts { @Scripts.Render("~/bundles/jqueryval") }似乎已经解决了我的脚本乱序加载的问题
。...– petrosmm

Answers:


103

默认情况下,带通配符的名称的绑定顺序是字母顺序的(如注释中所指出)。但是,它也根据它认为您的依赖关系树的顺序进行排序,并且jQuery脚本似乎排在最前面。您需要创建一个实现IBundleOrder以下内容的对象:

class NonOrderingBundleOrderer : IBundleOrderer
{
    public IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
    {
        return files;
    }
}

这样可以防止默认排序。现在使用它:

var bundle = new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new NonOrderingBundleOrderer();

bundles.Add(bundle);

参考:http : //stevescodingblog.co.uk/changing-the-ordering-for-single-bundles-in-asp-net-4/

为了进一步阅读,MikeSmithDev问题的答案可以进一步了解流行脚本库的默认顺序:

捆绑软件中文件的排序-已知的库是什么?


当您使用通配符之类的东西时,“默认情况下,绑定顺序是字母顺序的”是正确的……当您指定顺序(如他的顺序)时,它应该使用他的顺序。我只能假设捆绑程序正在移动已知的文件类型,而忽略了他的顺序。
MikeSmithDev

看起来捆绑程序也使用一些有关依赖关系的逻辑进行排序。它认为这jquery.validate.globalize.js是其他两个所必需的。来自裁判:“ [捆绑器甚至会自动将已知的框架javascript文件自动放入捆绑包中,例如jQuery或Prototype脚本,以确保它们在使用自己的类型的代码执行之前运行”
Mister Epic

3
具体的顺序是:jquery.js jquery-min.js jquery- * jquery-ui * jquery.ui * jquery.unobtrusive * jquery.validate * modernizr- * dojo。* mootools-core * mootools- * prototype.js prototype- * scriptaculous- * ext.js ext- *
ravndal

6
这是编程不好玩的地方。为什么VS使这个变得复杂?
贾德2014年

5
这种存在的事实让我震惊,这是多么愚蠢。真的..捆绑器比我键入依赖项更了解如何排序依赖项?Gulp.js(甚至Grunt)FTW!
John Culviner '16

30

在MVC 5的最新版本(2014年10月27日)中,您应改用此类:

class AsIsBundleOrderer : IBundleOrderer
{
    public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}

然后像其他响应一样创建捆绑包:

var bundle = new ScriptBundle("~/bundles/globalization")
.Include("~/Scripts/globalize/globalize.js")
.Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
.Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new AsIsBundleOrderer();

bundles.Add(bundle);

在哪里可以找到此信息?你能提供一个链接吗?
PussInBoots 2014年

我只是尝试对这一问题的电流响应的方法,但我发现我的selkf在ASP.NET MVC 5的错误,所以我检查IBundleOrderer接口和所做的更改
塞巴斯蒂安·罗哈斯

没有订购者属性。我正在使用MVC 5.2.x
Legends

1
我只是用MVC 5.2.3进行了测试,这是Orderer属性。
塞巴斯蒂安·罗哈斯

28

为了减少创建包时的代码,建议您创建一个扩展方法。

需要基础设施类:

class NonOrderingBundleOrderer : IBundleOrderer
{
    public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
    {
        return files;
    }
}


static class BundleExtentions
{
    public static Bundle NonOrdering(this Bundle bundle)
    {
        bundle.Orderer=new NonOrderingBundleOrderer();
        return bundle;
    }
}

现在只需像这样使用它:

多合一命令😎

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
               .NonOrdering()
               .Include(
                    "~/Scripts/globalize/globalize.js",
                    "~/Scripts/globalize/cultures/globalize.culture.es-CL.js",
                    //...
                );

1
不错的思维方式!
阿鲁娜
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.