Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload bundled and minified files to Windows Azure CDN

I'm using the ASP.NET MVC 4 bundling and minifying features in the Microsoft.AspNet.Web.Optimization namespace (e.g. @Styles.Render("~/content/static/css")).

I'd like to use it in combination with a Windows Azure CDN.

I looked into writing a custom BundleTransform but the content is not optimized there yet.

I also looked into parsing and uploading the optimized stream on runtime but that feels like a hack to me and I don't really like it:

@StylesCdn.Render(Url.AbsoluteContent(     Styles.Url("~/content/static/css").ToString()     ));  public static IHtmlString Render(string absolutePath) {     // get the version hash     string versionHash = HttpUtility.ParseQueryString(         new Uri(absolutePath).Query         ).Get("v");      // only parse and upload to CDN if version hash is different     if (versionHash != _versionHash)     {         _versionHash = versionHash;          WebClient client = new WebClient();         Stream stream = client.OpenRead(absolutePath);          UploadStreamToAzureCdn(stream);     }      var styleSheetLink = String.Format(         "<link href=\"{0}://{1}/{2}/{3}?v={4}\" rel=\"stylesheet\" type=\"text/css\" />",         cdnEndpointProtocol, cdnEndpointUrl, cdnContainer, cdnCssFileName, versionHash         );      return new HtmlString(styleSheetLink); } 

How can I upload the bundled and minified versions automatically to my Windows Azure CDN?

like image 527
Martin Buberl Avatar asked Aug 21 '12 03:08

Martin Buberl


People also ask

What are the different ways for bundling and minification in asp net core?

Bundling and minification are two techniques you can use in ASP.NET to improve page load performance for your web application. Bundling combines multiple files into a single file. Minification performs a variety of different code optimizations to scripts and CSS, which results in smaller payloads.

What is bundling and minification?

Bundling and minification are two techniques you can use in ASP.NET 4.5 to improve request load time. Bundling and minification improves load time by reducing the number of requests to the server and reducing the size of requested assets (such as CSS and JavaScript.)

How do I upload to Azure CDN?

Sign in to the Azure portal. From the left menu, select Storage accounts, then select the name of your storage account. Select Containers, then select the thumbnails container. Select Upload to open the Upload blob pane.

What is the difference between Azure front door and Azure CDN?

Azure CDN is best for delivering static content like Videos, Images and PDFs whereas Azure Front Door is for delivering sites, services and APIs. Azure CDN is cost-effective whereas Azure Front Door charges per ruleset. Azure CDN does all the functionality similar to Azure Front Door.


1 Answers

Following Hao's advice I Extended Bundle and IBundleTransform.

Adding AzureScriptBundle or AzureStyleBundle to bundles;

bundles.Add(new AzureScriptBundle("~/bundles/modernizr.js", "cdn").Include("~/Scripts/vendor/modernizr.custom.68789.js")); 

Results in;

<script src="//127.0.0.1:10000/devstoreaccount1/cdn/modernizr.js?v=g-XPguHFgwIb6tGNcnvnI_VY_ljCYf2BDp_NS5X7sAo1"></script> 

If CdnHost isn't set it will use the Uri of the blob instead of the CDN.

Class

using System; using System.Text; using System.Web; using System.Web.Optimization; using System.Security.Cryptography; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.StorageClient;  namespace SiegeEngineWebRole.BundleExtentions {     public class AzureScriptBundle : Bundle     {         public AzureScriptBundle(string virtualPath, string containerName, string cdnHost = "")             : base(virtualPath, null, new IBundleTransform[] { new JsMinify(), new AzureBlobUpload { ContainerName = containerName, CdnHost = cdnHost } })         {             ConcatenationToken = ";";         }     }      public class AzureStyleBundle : Bundle     {         public AzureStyleBundle(string virtualPath, string containerName, string cdnHost = "")             : base(virtualPath, null, new IBundleTransform[] { new CssMinify(), new AzureBlobUpload { ContainerName = containerName, CdnHost = cdnHost } })         {         }     }      public class AzureBlobUpload : IBundleTransform     {         public string ContainerName { get; set; }         public string CdnHost { get; set; }          static AzureBlobUpload()         {         }          public virtual void Process(BundleContext context, BundleResponse response)         {             var file = VirtualPathUtility.GetFileName(context.BundleVirtualPath);              if (!context.BundleCollection.UseCdn)             {                 return;             }             if (string.IsNullOrWhiteSpace(ContainerName))             {                 throw new Exception("ContainerName Not Set");             }              var conn = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString"));             var blob = conn.CreateCloudBlobClient()                 .GetContainerReference(ContainerName)                 .GetBlobReference(file);              blob.Properties.ContentType = response.ContentType;             blob.UploadText(response.Content);              var uri = string.IsNullOrWhiteSpace(CdnHost) ? blob.Uri.AbsoluteUri.Replace("http:", "").Replace("https:", "") : string.Format("//{0}/{1}/{2}", CdnHost, ContainerName, file);              using (var hashAlgorithm = CreateHashAlgorithm())             {                 var hash = HttpServerUtility.UrlTokenEncode(hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(response.Content)));                 context.BundleCollection.GetBundleFor(context.BundleVirtualPath).CdnPath = string.Format("{0}?v={1}", uri, hash);             }         }          private static SHA256 CreateHashAlgorithm()         {             if (CryptoConfig.AllowOnlyFipsAlgorithms)             {                 return new SHA256CryptoServiceProvider();             }              return new SHA256Managed();         }     } } 
like image 80
Daniel Avatar answered Oct 09 '22 02:10

Daniel