我有一個Angular.js應用程序,並且由於它是單頁應用程序,因此我根據用戶導航動態加載一些腳本,因此我不會沒有過載。如果動態加載ASP.NET MVC包,它將不會更新
問題是,其中一些腳本在ASP.NET MVC Bundle中被縮小和縮小,並且當我更新源腳本時,導入的bundle永遠不會被更新。
爲什麼會發生這種情況,我該如何強制更新?
我有一個Angular.js應用程序,並且由於它是單頁應用程序,因此我根據用戶導航動態加載一些腳本,因此我不會沒有過載。如果動態加載ASP.NET MVC包,它將不會更新
問題是,其中一些腳本在ASP.NET MVC Bundle中被縮小和縮小,並且當我更新源腳本時,導入的bundle永遠不會被更新。
爲什麼會發生這種情況,我該如何強制更新?
爲什麼出現這種情況
的ASP.NET捆綁自帶緩存機制。當您使用Scripts.Render
將軟件包添加到頁面時,引擎會自動將v
查詢字符串放入軟件包URL中。
@Scripts.Render("~/bundles/commands")
產生類似:
<script src="/bundles/commands?v=eiR2xO-xX5H5Jbn3dKjSxW7hNCH9DfgZHqGApCP3ARM1"></script>
如果未提供此參數,緩存的結果將被退回。如果手動添加腳本標記,沒有它,您可能面臨相同的緩存問題。
信息有關v
查詢字符串提供here(「包緩存」),但不是非常有幫助。
我能做些什麼
您仍然可以加載捆綁腳本動態,但你必須添加v
參數。請注意,如果您嘗試使用隨機生成的散列(我試過),則它不起作用。由於Frison B Alexander,這是可能使用這種方法:
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();
}
所以你可以做的是:從ASP.NET視圖返回該包的哈希,並得到它時,你需要加載腳本。
我我的申請,我創建特定於它的一個JS對象:
var appBundles = {
commands: "/bundles/commands?v=eiR2xO-xX5H5Jbn3dKjSxW7hNCH9DfgZHqGApCP3ARM1"
};
希望這有助於!
當我從一個MVC應用程序中使用GTM從另一個MVC應用程序加載包時,我遇到了捆綁包未更新的問題(聲音混亂了,但實際上在多個MVC應用程序共享代碼的上下文中有意義)。
我想出的是馬科斯利馬在他的回答中所寫的,但更進一步。
我已經添加了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/
路徑中,但如果將其放置在其他位置,該路徑應該很容易更改。事實上,這條路線甚至沒有必要。