How to Transform Styles Urls to CDN Urls in ASP.NET Bundling and Minification

Total Post:341

Points:2389
 1215  View(s)
Ratings:
Rate this:

Some of my styles use url(../img/sprites/main_sprite.png) to local resources in development and stage. However in production I use CDN and all my static resources are on it. Is it possible to transform bundles so that all urls in .css are replaced with cdn path?

For Example:

.Logo {
background-image: url(../img/sprites/main_sprite.png); 
}
However, in production I would like it to be
.Logo {
background-image: url(http://MyCdn.com/img/sprites/main_sprite.png);   
}
I already use CssRewriteUrlTransform() to rewrite my relative paths to absolute, so the resources can be found after they bundled.
I was thinking to extend the class as something like this
public string Process(string includedVirtualPath, string input)

    if (_useCdn)
        {
             return  new CssRewriteUrlTransform().Process(_cdn + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);                          
        }
        else
        {
             return  new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
        }
 
    }

However, Process must have VirtualPath, otherwise it throws an exception when I append CDN path.

Is there an equivalent of this class to rewrite URLS with CDN in it?

 

  1. Post:134

    Points:940
    Re: How to Transform Styles' Urls to CDN Urls in ASP.NET Bundling and Minification

    I was not able to find an existing solution. So, I used CssRewriteUrlTransform code as the base for my CDNStylesTransformer. I hope it will be useful for you too.

    /// <summary>
    /// Finds and Replaces Urls with CDN links.
    /// </summary>
    public class CDNStylesTransformer : IItemTransform
    {
        private bool _useCdn;
        private string _cdnBaseUrl;
        public CDNStylesTransformer(bool UseCDN, string CdnBaseUrl)
        {
            _useCdn = UseCDN;
            if(CdnBaseUrl ==null || CdnBaseUrl.Equals(string.Empty))
            {
                throw new ArgumentNullException("CdnBaseUrl");
            }
            _cdnBaseUrl = CdnBaseUrl;
     
        }
     
        internal static string RebaseUrlToCDNUrl(string cdnUrl, string url)
        {
            // Don't do anything to invalid urls or absolute urls
            if (String.IsNullOrWhiteSpace(url)||
                String.IsNullOrWhiteSpace(url)||
                url.StartsWith("data:")||
                   !VirtualPathUtility.IsAbsolute(url))
            {
                return url;
            }
     
            return cdnUrl +url;
        }
     
        internal static string ConvertUrlsToCDNUrl(string cdnUrl, string content)
        {
            if (String.IsNullOrWhiteSpace(content))
            {
                return content;
            }
            // Replace all urls with CDN urls
            Regex url = new Regex(@"url\(['""]?(?<url>[^)]+?)['""]?\)");
            return url.Replace(content,((match) =>
            {
                return "url("+ RebaseUrlToCDNUrl(cdnUrl, match.Groups["url"].Value) + ")";
            }));
        }
     
        public  string Process(string includedVirtualPath, string input)
        {
            if (_useCdn)
            {
     
                return ConvertUrlsToCDNUrl(_cdnBaseUrl,input);
            }
            else
            {
                return input; //do nothing
     
            }
        }
    }

    In your BundleConfiguration class

    string cdnPath ="http://MyCdn.com";
    bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
          "~/Content/themes/base/style1.css", new CDNStylesTransformer(bundles.UseCdn,cdnPath)
          ));

     

      Modified On Apr-07-2018 06:15:34 AM

Answer