ASP.NET MVC4绑定到单个文件

ASP.NET MVC4绑定到单个文件,asp.net,asp.net-mvc-4,bundling-and-minification,Asp.net,Asp.net Mvc 4,Bundling And Minification,有没有办法使用MVC4中的新绑定功能绑定单个文件?我知道捆绑单个文件没有多大意义,但我希望使用服务器端缩小,并让MVC在URL的末尾附加一个哈希值以进行缓存 我尝试了@Scripts.Url(“~/Scripts/myscript.js”),但它似乎不起作用。好吧,请在捆绑包配置中定义一个只包含此文件的捆绑包: bundles.Add( new ScriptBundle("~/bundles/myscript").Include("~/Scripts/myscript.js") );

有没有办法使用MVC4中的新绑定功能绑定单个文件?我知道捆绑单个文件没有多大意义,但我希望使用服务器端缩小,并让MVC在URL的末尾附加一个哈希值以进行缓存


我尝试了
@Scripts.Url(“~/Scripts/myscript.js”)
,但它似乎不起作用。

好吧,请在捆绑包配置中定义一个只包含此文件的捆绑包:

bundles.Add(
    new ScriptBundle("~/bundles/myscript").Include("~/Scripts/myscript.js")
);
然后在视图中按名称引用它:

@Scripts.Render("~/bundles/myscript")

我不知道,如果我没弄错,但您可以随时添加捆绑包,只需将其添加到bundlecollection:

BundleTable.Bundles.Add(new ScriptBundle("~/Scripts/myBundleName").Include(
            "~/Scripts/myscript.js"
            ));
我不确定您计划如何在客户端包含该捆绑包,但在注册捆绑包后,您可以使用以下代码获取缩小脚本文件的url:

string url = BundleTable.Bundles.ResolveBundleUrl("~/Scripts/myBundleName");
在我的例子中,我只是通过ajax请求获得这个url,并在客户端创建一个脚本标记。通过这种方式,脚本文件将被缩小,url带有一个哈希代码,因此浏览器应该缓存它,当包被更改时,应该加载较新的版本


我希望这就是你想要做的。

我需要这样的东西,这就是我想到的

在视图上,我可以添加带有HTML帮助器的脚本或样式。这些将分别接受n个参数

@Html.Style("~/Styles/someFile.css")
@Html.Script("~/Scripts/foo.js", "~/Scripts/bar.js")
所以我创建了一个扩展来处理这个问题。这是这门课的样子

using System.Linq;
using System.Web.Optimization;

namespace System.Web.Mvc
{
    public static class HtmlHelperExtensions
    {

        public static IHtmlString Script(this HtmlHelper helper, params string[] urls)
    {
        var bundleDirectory = "~/Scripts/bundles/" + MakeBundleName(".js", urls);
        var thisBundle = new ScriptBundle(bundleDirectory).Include(urls);
        BundleTable.Bundles.Add(thisBundle);

        return Scripts.Render(bundleDirectory);
    }

    public static IHtmlString Style(this HtmlHelper helper, params string[] urls)
    {
        var bundleDirectory = "~/Styles/bundles/" + MakeBundleName(".css", urls);
        var thisBundle = new StyleBundle(bundleDirectory).Include(urls);
        BundleTable.Bundles.Add(thisBundle);

        return Styles.Render(bundleDirectory);
    }

    private static string MakeBundleName(string type, params string[] urls)
    {
        var bundleSections = new List<string>();

        foreach (var item in urls)
        {
            bundleSections.Add(item.Replace("~/", "").Replace("/", ".").Replace(type, ""));
        }

        return string.Join("+", bundleSections.ToArray());
    }
    }
}
使用System.Linq;
使用System.Web.Optimization;
命名空间System.Web.Mvc
{
公共静态类HtmlHelperExtensions
{
公共静态IHtmlString脚本(此HtmlHelper帮助程序,参数字符串[]URL)
{
var bundleDirectory=“~/Scripts/bundles/”+MakeBundleName(“.js”,URL);
var thisBundle=newscriptbundle(bundleDirectory).Include(URL);
BundleTable.Bundles.Add(这个bundle);
返回Scripts.Render(bundleDirectory);
}
公共静态IHtmlString样式(此HtmlHelper帮助程序,参数字符串[]URL)
{
var bundleDirectory=“~/Styles/bundles/”+MakeBundleName(“.css”,URL);
var thisBundle=newstylebundle(bundleDirectory).Include(url);
BundleTable.Bundles.Add(这个bundle);
返回Styles.Render(bundleDirectory);
}
私有静态字符串MakeBundleName(字符串类型,参数字符串[]URL)
{
var bundleSections=新列表();
foreach(URL中的变量项)
{
bundleSections.Add(item.Replace(“~/”,”).Replace(“/”,”).Replace(type,”);
}
返回字符串.Join(“+”,bundleSections.ToArray());
}
}
}

警告 这会在捆绑包“虚拟目录”存在的地方进行硬编码。因此,如果文件中有任何指向图像或其他任何内容的相对路径,它们将中断。对于我们的用例来说,现在这对我们来说很好

捆绑包名称是自动生成的。同样,这对我们来说是有效的,但可能更好。我可以看到一个简单的改进,您必须提供一个bundle路径和名称,其语法如下:
@Html.Script(“~/bundles/myBundleName”,“~/Scripts/foo.js”,“~/Scripts/bar.js”)



我很高兴听到任何人对此可能有任何改进。

问题是我们的网站非常动态,因为我们有许多白色标签,所以在Global.asax文件中添加BundleTable不是一个选项-有没有一种方法可以在运行时执行?您所说的“运行中”是什么意思?请提供更多详情。如果你有很多脚本,你应该考虑把它们分组在文件夹中,并在每个功能上捆绑它们。看起来我只能在应用程序启动时登记一个包。如果我在Global.axax文件之外尝试上面的代码,它将不起作用。我需要能够在应用程序期间的任何时间“注册”捆绑包,这更有意义吗?何时/为什么需要在
应用程序\u Start
外部注册捆绑包?因为我们的网站非常动态,我们有数百个不同的白标签/皮肤和每个“皮肤”有一堆每天都在变化的Javascript文件。将每个CSS/JS文件放入
AppStart
将是一场噩梦。谢谢,我只是走了同一条路,很高兴有人走了这条路。您还应该使用System.Collections.Generic添加
这段代码不是在为每个页面视图创建一个新的捆绑包吗?或者MVC是否正确处理BundleTable中的重复捆绑包(即,如果它具有相同的名称,则旧的捆绑包将被删除?)。还有,它是多线程安全的吗(如果两个请求试图同时访问BundleTable.Bundles)@youen我不是100%确定你所有的问题,但我相信一旦创建了一个bundle,它就会被缓存。因此,它应该在第一次访问时创建,然后缓存版本将在以后的任何时间被访问。@ChrisBarr确实,浏览器将缓存文件,没有问题。但是在服务器端,每次调用
BundleTable.Bundles.Add
时,您都会在表中添加一个新条目(我已经用调试器检查过了)。这可能不是一个很大的成功,但可能在数千次请求之后,它将开始使用一点内存,这使得MVC更难在列表中找到特定的包。解决方案只是在添加新的包之前检查该包是否已经存在(相同的名称)。