【问题标题】:MVC 5 bundling and Azure CDN (query string)MVC 5 捆绑和 Azure CDN(查询字符串)
【发布时间】:2016-06-03 06:50:45
【问题描述】:

我一直在关注这个教程:https://azure.microsoft.com/en-us/documentation/articles/cdn-serve-content-from-cdn-in-your-web-application/

一切都很好,直到我注意到捆绑的脚本和 CSS 文件返回 cache: no-cacheexpires: -1pragma: no-cache 标头。 当然,这与 Azure 无关。为了证明这一点,我通过直接从我的站点而不是 CDN 访问它们来测试捆绑包 - 即。 mysite.com/bundles/mybundle?v={myassemblyversion}。结果是一样的。当我禁用 CDN,并使用 MVC 生成的 v 查询字符串访问捆绑文件时,标题如预期:公共缓存,到期时间为一年。

我尝试实现IBundleTransform 接口,但context.BundleVirtualPath 是只读的(即使它说获取或设置虚拟路径...)。我也尝试修改Application_EndRequest() 处的响应标头,但也没有用。我最后的赌注是编写 IIS 出站规则,但由于我的包(与“自定义”v 查询字符串一起使用)不返回 Last-Modified 标头,所以这也是徒劳的尝试。

我的问题是:如果我希望我的捆绑文件缓存在客户端上,我该如何使用 MVC 捆绑与 Azure CDN - 也就是说,直到v 查询字符串发生变化?

【问题讨论】:

    标签: asp.net-mvc azure caching model-view-controller bundling-and-minification


    【解决方案1】:

    我知道我玩游戏有点晚了,但我确实找到了解决方法。我正在使用 Frison B Alexander here 的代码。

    问题在于,一旦您为 StyleBundle 或 ScriptBundle 重写查询字符串,一年的默认缓存行为将重置为无缓存。这可以通过为每个包重新生成完全相同的查询字符串来解决,MVC 框架在指定每个包的 CDNPath 时使用该查询字符串。

    以下是使用 MVC Web 应用模板的方法。这是 BundleConfig 类:

    public class BundleConfig
        {
            public static void RegisterBundles(BundleCollection bundles)
            {            
                //we have to go ahead and add our Bundles as if there is no CDN involved.
                //this is because the bundle has to already exist in the BundleCollection
                //in order to get the hash that the MVC framework will generate for the
                //querystring. 
                Bundle jsBundle = new ScriptBundle("~/scripts/js3").Include(
                     "~/Scripts/jquery-{version}.js",
                     "~/Scripts/modernizr-*",
                     "~/Scripts/bootstrap.js",
                     "~/Scripts/respond.js");
                bundles.Add(jsBundle);
    
                Bundle cssBundle = new StyleBundle("~/content/css3").Include(
                          "~/Content/bootstrap.css",
                          "~/Content/site.css");
                bundles.Add(cssBundle);
    
    #if Debug
                bundles.UseCdn = false; 
    #else
                bundles.UseCdn = true;
                //grab our base CDN hostname from web.config...
                string cdnHost = ConfigurationManager.AppSettings["CDNHostName"];
    
                //get the hashes that the MVC framework will use per bundle for 
                //the querystring. 
                string jsHash = GetBundleHash(bundles, "~/scripts/js3");
                string cssHash = GetBundleHash(bundles, "~/content/css3");
    
                //set up our querystring per bundle for the CDN path. 
                jsBundle.CdnPath = cdnHost + "/scripts/js3?v=" + jsHash;
                cssBundle.CdnPath = cdnHost + "/content/css3?v=" + cssHash;
    #endif
            }
    
            //Frison B Alexander's code:
            private static string GetBundleHash(BundleCollection bundles, string bundlePath)
            {
    
                //Need the context to generate response
                var bundleContext = new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, bundlePath);
    
                //Bundle class has the method we need to get a BundleResponse
                Bundle bundle = BundleTable.Bundles.GetBundleFor(bundlePath);
                var bundleResponse = bundle.GenerateBundleResponse(bundleContext);
    
                //BundleResponse has the method we need to call, but its marked as
                //internal and therefor is not available for public consumption.
                //To bypass this, reflect on it and manually invoke the method
                var bundleReflection = bundleResponse.GetType();
    
                var method = bundleReflection.GetMethod("GetContentHashCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    
                //contentHash is whats appended to your url (url?###-###...)
                var contentHash = method.Invoke(bundleResponse, null);
                return contentHash.ToString(); 
            }
        }
    

    【讨论】:

    • 没有使用参数BundleCollection bundles
    猜你喜欢
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 2018-06-17
    • 1970-01-01
    相关资源
    最近更新 更多