Prepend CDN url to mvc 4 bundler output

asp.net-mvc-4, bundling-and-minification, c#, cdn

Solution

I just setup MaxCDN and ran into the same exact issue.

As you know, the `bundles.UseCdn` property is not ideal because we don't want to have to specify the exact url for the bundle. A CDN like Max CDN is the same exact url, query string and all, except for a different subdomain.

Here is how I ended up solving it.

I created a `BundleHelper` class that will wrap the render method and then prepend the path with the CDN subdomain.

Here is what the class looks like:

namespace MyDomain.Web.Helpers
{
    public class BundleHelper
    {
        public static string CdnPath = "http://cdn.mydomain.com";

        public static IHtmlString RenderScript(string path)
        {
            var opt = System.Web.Optimization.Scripts.Render(path);
            string htmlString = HttpUtility.HtmlDecode(opt.ToHtmlString());

            if (BundleTable.EnableOptimizations)
            {
                htmlString = htmlString.Replace("<script src=\"/", String.Format("<script src=\"{0}/", CdnPath));
            }

            return new HtmlString(htmlString);
        }

        public static IHtmlString RenderStyle(string path)
        {
            var opt = System.Web.Optimization.Styles.Render(path);
            string htmlString = HttpUtility.HtmlDecode(opt.ToHtmlString());

            if (BundleTable.EnableOptimizations)
            {
                htmlString = htmlString.Replace("<link href=\"/", String.Format("<link href=\"{0}/", CdnPath));
            }

            return new HtmlString(htmlString);
        }
    }
}

Then to use it in the views, I simply do:

@BundleHelper.RenderStyle("~/Content/css")
@BundleHelper.RenderStyle("~/Content/themes/base/css")

@BundleHelper.RenderScript("~/bundles/jquery")
@BundleHelper.RenderScript("~/bundles/jqueryui")

Hope this helps.

Problem

Using the built in MVC4 bundler, how do I prepend my CDN url to the link tags it produces? I've setup Amazon Cloudfront so that it pulls assets from my webserver when first requested. So when I define a bundle like so: ``` bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/reset.css", "~/Content/960_24_col.css", "~/Content/Site.css" )); ``` When deployed, I can reference it thus: ``` http://[cloundfrontid].cloudfront.net/Content/css?v=muhFMZ4thy_XV3dMI2kPt-8Rljm5PNW0tHeDkvenT0g1 ``` Now I just need to change the links produced by the bundler from being relative to absolute links pointing to my CDN. ``` <link href="[INSERT_CDN_URL_HERE]/Content/css?v=muhFMZ4thy_XV3dMI2kPt-8Rljm5PNW0tHeDkvenT0g1" rel="stylesheet"/> ``` I think it may be possible to rewrite the path using IBundleTransform but I can't find any examples of this. NOTE: Just to be clear, I know you can specify a CDN link for a bundle, but that only works if the bundle can be replaced by a static link.

Original source