加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – MVC 5捆绑和Azure CDN(查询字符串)

发布时间:2020-12-16 03:45:46 所属栏目:asp.Net 来源:网络整理
导读:我一直在关注本教程: https://azure.microsoft.com/en-us/documentation/articles/cdn-serve-content-from-cdn-in-your-web-application/ 一切都很好,直到我注意到捆绑的脚本和CSS文件返回缓存:no-cache,expires:-1和pragma:no-cache headers. 当然,这与
我一直在关注本教程: https://azure.microsoft.com/en-us/documentation/articles/cdn-serve-content-from-cdn-in-your-web-application/

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

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

我的问题是:如果我希望将捆绑的文件缓存在客户端上,那么我如何使用Azure CDN绑定MVC – 也就是说,直到v查询字符串更改?

解决方法

我知道我的比赛有点晚了,但我确实找到了一个解决方法.我正在使用Frison B Alexander here的代码.

问题是,一旦为StyleBundles或ScriptBundles重写查询字符串,一年的默认缓存行为将重置为no-cache.这可以通过重新生成MVC框架在指定每个Bundle的CDNPath时使用的每个bundle完全相同的查询字符串来解决.

以下是使用MVC Web App模板完成的工作.这是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(); 
        }
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读