如果动态加载,ASP.NET MVC包不会更新

时间:2015-10-13 12:47:39

标签: angularjs asp.net-mvc bundling-and-minification

我有一个Angular.js应用程序,因为它是一个单页面应用程序,我根据用户导航动态加载一些脚本,所以我没有过载。

问题是,其中一些脚本在ASP.NET MVC Bundle中被修改和缩小,当我更新源脚本时,导入的bundle永远不会更新。

为什么会发生这种情况,我该怎么做才能强制更新?

2 个答案:

答案 0 :(得分:3)

为什么会这样?

ASP.NET包附带了一个缓存机制。使用v将捆绑包添加到页面时,引擎会自动将@Scripts.Render("~/bundles/commands") 查询字符串放入捆绑包URL中。

<script src="/bundles/commands?v=eiR2xO-xX5H5Jbn3dKjSxW7hNCH9DfgZHqGApCP3ARM1"></script>

产生类似的东西:

v

如果未提供此参数,则将返回缓存的结果。如果手动添加脚本标记,没有它,则可能会遇到相同的缓存问题。

提供了v查询字符串的信息here(“ Bundle Caching ”),但不是很有帮助。

我该怎么办

您仍然可以动态加载捆绑的脚本,但您必须添加private static string GetHashByBundlePath(string bundlePath) { BundleContext bundleContext = new BundleContext(new HttpContextWrapper(System.Web.HttpContext.Current), BundleTable.Bundles, bundlePath); Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath); BundleResponse bundleResponse = bundle.GenerateBundleResponse(bundleContext); Type bundleReflection = bundleResponse.GetType(); MethodInfo method = bundleReflection.GetMethod("GetContentHashCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); object contentHash = method.Invoke(bundleResponse, null); return contentHash.ToString(); } 参数。请注意,如果您尝试随机生成的哈希(我尝试过),它不起作用。感谢Frison B Alexander,可以使用这种方法:

var appBundles = {
    commands: "/bundles/commands?v=eiR2xO-xX5H5Jbn3dKjSxW7hNCH9DfgZHqGApCP3ARM1"
};

所以你可以做的是:从ASP.NET视图返回bundle hash,并在需要加载脚本时获取它。

我是我的应用程序,我创建了一个特定于它的JS对象:

char*

希望这有帮助!

答案 1 :(得分:0)

我在使用GTM从另一个MVC应用程序中的一个MVC应用程序加载捆绑包时没有更新捆绑包时出现此问题(声音搞砸了,但它实际上在多个MVC应用程序之间共享代码的情况下有意义。)

我想出的是Marcos Lima在他的回答中所写的内容,但更进一步。

我添加了一个Bundle控制器,其中包含以下代码:

public class BundleController : Controller
{
    private static string GetHashByBundlePath(string bundlePath)
    {
        BundleContext bundleContext = new BundleContext(new HttpContextWrapper(System.Web.HttpContext.Current), BundleTable.Bundles, bundlePath);
        Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath);
        BundleResponse bundleResponse = bundle.GenerateBundleResponse(bundleContext);
        Type bundleReflection = bundleResponse.GetType();
        MethodInfo method = bundleReflection.GetMethod("GetContentHashCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        object contentHash = method.Invoke(bundleResponse, null);
        return contentHash.ToString();
    }

    public ActionResult Index(string bundleName)
    {
        string bundlePath = "~/bundles/" + bundleName;
        var hash = GetHashByBundlePath(bundlePath);
        return RedirectPermanent(bundlePath + "?v=" + hash);
    }
}

然后我添加了这条路线:

routes.MapRoute(
    name: "Bundle",
    url: "Bundle/{bundleName}",
    defaults: new { controller = "Bundle", action = "Index" }
);

最终结果是我通过控制器请求捆绑包,但因为我执行301重定向,Index操作每个用户只运行一次,它返回捆绑包的当前版本,然后捆绑包之后从浏览器缓存中提供。当我实际更新捆绑包时,我在请求URL中添加了一些查询参数(在GTM中),所有用户现在都获得了更新的捆绑包。

当然,我认为捆绑包放在~/bundles/路径中,但是如果将它们放在其他位置,这应该很容易改变。事实上,这条路线甚至是不必要的。