2015-10-13 41 views
2

我有一個Angular.js應用程序,並且由於它是單頁應用程序,因此我根據用戶導航動態加載一些腳本,因此我不會沒有過載。如果動態加載ASP.NET MVC包,它將不會更新

問題是,其中一些腳本在ASP.NET MVC Bundle中被縮小和縮小,並且當我更新源腳本時,導入的bundle永遠不會被更新。

爲什麼會發生這種情況,我該如何強制更新?

回答

2

爲什麼出現這種情況

的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" 
}; 

希望這有助於!

0

當我從一個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/路徑中,但如果將其放置在其他位置,該路徑應該很容易更改。事實上,這條路線甚至沒有必要。