MVC 5 and Azure CDN (query string)

I follow this guide: https://azure.microsoft.com/en-us/documentation/articles/cdn-serve-content-from-cdn-in-your-web-application/

Everything was great until I noticed that the associated scripts and CSS files are returned with the headers cache: no-cache , expires: -1 and pragma: no-cache . Of course, this has nothing to do with Azure. To prove this, I checked the packages by accessing them directly from my site, not the CDN - i.e. mysite.com/bundles/mybundle?v= {myassemblyversion} . The result was the same. When I unplugged the CDN and accessed the linked file with the MVC-generated query string v , the headers were as expected: public caching with one year expiration.

I tried to implement the IBundleTransform interface, but context.BundleVirtualPath is read-only (although it says it gets or sets the virtual path ...). I also tried changing the response headers to Application_EndRequest() , but that didn't work either. My last bet was to write outgoing IIS rules, but since my packages (used with the "custom" query string v) do not return the Last-Modified header, this is also a futile attempt.

My question is: how can I use MVC binding with Azure CDN if I want my related files to be cached on the client, that is, until the query string v changes?

+5
source share
1 answer

I know I was a little late to the game, but I found a workaround. I am using the Frison B Alexander code here .

The problem is that after overwriting a request for StyleBundles or ScriptBundles, the default caching behavior for one year is reset to no-cache. This is accomplished by regenerating exactly the same sequence of packet requests that MVC uses when specifying each CDNPath package.

Here's how to do it using the MVC web application template. Here's the BundleConfig class:

 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 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(); } } 
+1
source

Source: https://habr.com/ru/post/1243543/


All Articles