问题描述:

ASP.NET 4.5 has a great new bundling feature and appears to have some support for use of CDNs. The example given by Microsoft for use of the bundling feature with a CDN is this

public static void RegisterBundles(BundleCollection bundles)

{

//bundles.Add(new ScriptBundle("~/bundles/jquery").Include(

// "~/Scripts/jquery-{version}.js"));

bundles.UseCdn = true; //enable CDN support

//add link to jquery on the CDN

var jqueryCdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js";

bundles.Add(new ScriptBundle("~/bundles/jquery",

jqueryCdnPath).Include(

"~/Scripts/jquery-{version}.js"));

// Code removed for clarity.

}

Which seems to suggest that you need tell it explicitly the path to your file on the CDN.

The CloudFront CDN (and I presume many others) gives you a subdomain which mirrors your own. When you hit http://uniquesubdomain.cloudfront.net/js/myfile.js?v=1 it serves up http://mydomain.com/js/myfile.js?v=1

This way you can simply prefix all your links with http://uniquesubdomain.cloudfront.net/ and your files are server from CloudFront.

Is the ASP.NET 4.5 bundling feature compatible with this type of CDN? Is there a built-in way to have the bundling feature prefix all its links with your CDN domain?

Eg.

bundles.UseCdn = true;

var myBundle= new ScriptBundle("~/bundles/js", "https://uniquedomain.cloudfront.net/");

myBundle.Include("~/js/file1.js");

myBundle.Include("~/js/file2.js");

would cause

 <script src="https://uniquedomain.cloudfront.net/bundles/js?v=6y-qVPSK3RYOYHfPhOBDd92H4LjEjs-D3Hh2Yml6CXA1"></script>

网友答案:

This functionality is not built-in, but is possible with a couple of small helper methods. Here's what I'm using right now:

public static class Cdn
{
    private const string CdnRoot = "//cloudfrontdomainhere.com";

    private static bool EnableCdn
    {
        get
        {
            bool enableCdn = false;
            bool.TryParse(WebConfigurationManager.AppSettings["EnableCdn"], out enableCdn);
            return enableCdn;
        }
    }

    public static IHtmlString RenderScripts(string bundlePath)
    {
        if (EnableCdn)
        {
            string sourceUrl = CdnRoot + Scripts.Url(bundlePath);
            return new HtmlString(string.Format("<script src=\"{0}\"></script>", sourceUrl));
        }

        return Scripts.Render(bundlePath);
    }

    public static IHtmlString RenderStyles(string bundlePath)
    {
        if (EnableCdn)
        {
            string sourceUrl = CdnRoot + Styles.Url(bundlePath);
            return new HtmlString(string.Format("<link href=\"{0}\" rel=\"stylesheet\" />", sourceUrl));
        }

        return Styles.Render(bundlePath);
    }
}

Note that I have my own configuration setting called EnableCdn in the appSettings section of my config file. When called from a Razor view, this produces the correct ouput, which appends the CDN domain onto the paths.

In your Razor files just do Cdn.RenderScripts("~/pathtoscriptbundle")

网友答案:

Might not be exactly what you're looking for, but a lot of CDN's now act as a reverse proxy using DNS so you don't have to link your assets explicitly. I know Cloudflare does this and I'm sure others do too.

网友答案:

Another option, is to use the Scripts or Styles RenderFormat method like so. This was particularly useful for me as I customise the tagFormat occassionally to wrap references in conditional html comments, or append additional attributes like media="screen,print". The code is simpler because you can do the awkward Replace on a string, before it becomes a HTML-encoded string.

Alternatively, you could have the tagFormat as an optional parameter to those methods where the default value is the string constants mentioned below.

public class BundleHelper
{
    public static readonly string StyleTagFormat = "<link href=\"{0}\" rel=\"stylesheet\"/>";
    public static readonly string ScriptTagFormat = "<script src=\"{0}\"></script>"

    /// <summary>
    /// Customised script bundle rendering method with CDN support if optimizations and CDN enabled.
    /// </summary>
    public static IHtmlString RenderScriptFormat(string tagFormat, string path)
    {
        // Check for absolute url to ensure the standard framework support for CDN bundles, with a CdnPath still works.
        if (AppSettings.Bundling.EnableCdn && !UriHelper.IsAbsoluteUrl(Scripts.Url(path).ToString()))
        {
            tagFormat = tagFormat.Replace(" src=\"{0}\"", String.Format(" src=\"{0}{{0}}\"", AppSettings.Bundling.BundlesCDNPrefixUrl));
        }
        return Scripts.RenderFormat(tagFormat, path);
    }

    /// <summary>
    /// Customised styles bundle rendering method with CDN support if optimizations and CDN enabled.
    /// </summary>
    public static IHtmlString RenderStyleFormat(string tagFormat, string path)
    {
        // Check for absolute url to ensure the standard framework support for CDN bundles, with a CdnPath still works.
        if (AppSettings.Bundling.EnableCdn && !UriHelper.IsAbsoluteUrl(Styles.Url(path).ToString()))
        {
            tagFormat = tagFormat.Replace(" href=\"{0}\"", String.Format(" href=\"{0}{{0}}\"", AppSettings.Bundling.BundlesCDNPrefixUrl));
        }
        return Styles.RenderFormat(tagFormat, path);
    }
}


public class UriHelper
{
    /// <summary>
    /// Determines whether a url is absolute or not.
    /// </summary>
    /// <param name="url">Url string  to test.</param>
    /// <returns>true/false.</returns>
    /// <remarks>
    /// Examples:
    ///     ?IsAbsoluteUrl("hello")
    ///     false
    ///     ?IsAbsoluteUrl("/hello")
    ///     false
    ///     ?IsAbsoluteUrl("ftp//hello")
    ///     false
    ///     ?IsAbsoluteUrl("//hello")
    ///     true
    ///     ?IsAbsoluteUrl("ftp://hello")
    ///     true
    ///     ?IsAbsoluteUrl("http://hello")
    ///     true
    ///     ?IsAbsoluteUrl("https://hello")
    ///     true
    /// </remarks>
    public static bool IsAbsoluteUrl(string url)
    {
        Uri result;
        return Uri.TryCreate(url, UriKind.Absolute, out result);
    }
}
网友答案:

It is not possible, but instead of bundle you can use a text template to combine JS files as one js and put that on CDN.

<#@ ... hostspecific="true"  extension=".js">

<#

    Write (System.IO.File.ReadAllText("a.js"));
    Write (System.IO.File.ReadAllText("b.js"));
 #>
相关阅读:
Top