将CDN用于带有版本标记的ASP MVC Bundle

时间:2014-12-01 10:41:06

标签: asp.net-mvc cdn

我想在我的Bundles中使用CDN,但ASP MVC并不能为CDN网址本地处理版本。

例如:

public static void RegisterBundles(BundleCollection bundles)
{
    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"));
}

我无法使用{version}标记内部jqueryCdnPath,Framewok无法知道我想要远程网址中的本地版本。 有没有办法解决这个限制?如何检索本地版本以构建CDN URL?

1 个答案:

答案 0 :(得分:2)

我有一个选项,但只有在{version}中使用virtualPath标记时才有效。一些脚本(bootstrap,globalize,...)不需要版本标记,我无法知道要在CDN上引用的版本号。

private static string GetLastIncludedVirtualPath(this Bundle bundle)
{
  var files = bundle.EnumerateFiles(new BundleContext(new HttpContextWrapper(HttpContext.Current), new BundleCollection(), ""));
  var lastFile = files.LastOrDefault();
  if (lastFile == null)
    throw new InvalidOperationException("You must include a file so version can be extracted");
  return lastFile.IncludedVirtualPath;
}

public static Bundle IncludeWithVersionnedCdn(this Bundle bundle, string virtualPath, string cdnPath, params IItemTransform[] transforms)
{
  if (bundle == null)
    throw new ArgumentNullException("bundle");
  if (cdnPath == null)
    throw new ArgumentNullException("cdnPath");
  bundle.Include(virtualPath, transforms);
  //GetVersion
  int lengthBeforeVersion = virtualPath.IndexOf("{version}", StringComparison.OrdinalIgnoreCase);
  if (lengthBeforeVersion == -1)
    throw new ArgumentException("Path must contains {version} when version argument is not specified", "virtualPath");
  var includedPath = bundle.GetLastIncludedVirtualPath();
  int lengthAfterVersion = virtualPath.Length - lengthBeforeVersion - "{version}".Length;
  string version = includedPath.Remove(includedPath.Length - lengthAfterVersion).Substring(lengthBeforeVersion);
  //Set CDN
  bundle.CdnPath = cdnPath.Replace("{version}", version);
  return bundle;
}

用法:

bundles.Add(new ScriptBundle("~/bundles/jquery")
                .IncludeWithVersionnedCdn(
                    "~/Scripts/jquery-{version}.js",
                    "//ajax.aspnetcdn.com/ajax/jQuery/jquery-{version}.min.js"));