你的位置:首页 > ASP.net教程

[ASP.net教程]asp.net mvc自动压缩文件,并生成CDN引用


很多站点都是用了静态文件分离。我推荐一种处理静态文件分离的方式。

BundleExtensions.cs
 public static class BundleExtensions  {    public static string Version = "1.0.0";    public static string ScriptsPath = "Cdn";    public static Bundle Production(this Bundle bundle, string cdn, string root, string minified,      string full = "")    {      var transform = new ScriptsBundleTransform()      {        Version = Version,        ScriptsPath = System.IO.Path.Combine("~/", ScriptsPath, root),        Minified = minified,        Full = full      };      bundle.Transforms.Add(transform);      bundle.CdnPath = cdn + "/" + root + "/" + string.Format("{0}?{1}", minified, Version);      return bundle;    }  }

ScriptsBundleTransform.cs

public class ScriptsBundleTransform : IBundleTransform  {    public string ScriptsPath { get; set; }    public string Version { get; set; }    public string Minified { get; set; }    public string Full { get; set; }    public ScriptsBundleTransform()    {    }    public ScriptsBundleTransform(string path, string version, string minified, string full)    {      ScriptsPath = path;      Version = version;      Minified = minified;      Full = full;    }    public void Process(BundleContext context, BundleResponse response)    {      string scriptsRoot = context.HttpContext.Server.MapPath(ScriptsPath);      if (!Directory.Exists(scriptsRoot))        Directory.CreateDirectory(scriptsRoot);      // if minified file name specified...      if (!string.IsNullOrEmpty(Minified))      {        using (TextWriter writer = File.CreateText(Path.Combine(scriptsRoot, Minified)))        {          writer.Write(response.Content);        }      }      // if full file name specified...      if (!string.IsNullOrEmpty(Full))      {        using (Stream writer = File.OpenWrite(Path.Combine(scriptsRoot, Full)))        {          foreach (var file in response.Files)          {            file.VirtualFile.Open().CopyTo(writer);          }        }      }    }  }

BundleConfig.cs

    public static void RegisterBundles(BundleCollection bundles)    {      bundles.UseCdn = true;      BundleTable.EnableOptimizations = true;      //制定压缩后的资源存储路径      BundleExtensions.ScriptsPath = "Resource";      //制定请求时代的后缀,为了刷新掉客户端的缓存      BundleExtensions.Version = "00001";      //CDN站点地址      const string ajaxCdnPath = "http://localhost/Cdn";      bundles.Add(new ScriptBundle("~/bundles/bootstrap")        .IncludeFallback("$.fn.affix",          "~/Resource/Scripts/common/transition.js",          "~/Resource/Scripts/common/button.js",          "~/Resource/Scripts/common/affix.js",          "~/Resource/Scripts/common/tab.js",          "~/Resource/Scripts/common/collapse.js",          "~/Resource/Scripts/common/tooltip.js",          "~/Resource/Scripts/common/respond.js")        .Production(ajaxCdnPath, "Scripts", "bootstrap.mincdn.js", "bootstrap.src.js"));      bundles.Add(new ScriptBundle("~/Content/bootstrap")        .Include("~/Resource/Content/bootstrap.css")        .Include("~/Resource/Content/common/button.css")        .Include("~/Resource/Content/common/bootstrap-theme.css")        .Production(ajaxCdnPath, "Content", "bootstrap.mincdn.css", "bootstrap.src.css"));    }

 

这样的话就能生成 CDN 站点下的JS文件引用了

<script src="http://localhost/Cdn/Scripts/bootstrap.mincdn.js?00001"></script>

对了这里漏掉了一个地方,

http://localhost/Cdn站点需要你在IIS中指定到你站点的Resource下,不然访问不到你的JS文件。

但是如果CDN站点挂掉了怎么办,咱们继续:

SctiptsBundleExtensions.cs

  public static class SctiptsBundleExtensions  {    public static ScriptBundle IncludeFallback(this ScriptBundle bundle, string cdnFallbackExpression,      string virtualPath, params IItemTransform[] transforms)    {      bundle.CdnFallbackExpression = cdnFallbackExpression;      bundle.Include(virtualPath, transforms);      return bundle;    }    public static ScriptBundle IncludeFallback(this ScriptBundle bundle, string cdnFallbackExpression,     params string[] virtualPaths)    {      bundle.CdnFallbackExpression = cdnFallbackExpression;      bundle.Include(virtualPaths);      return bundle;    }  }

 


    bundles.Add(new ScriptBundle("~/bundles/jquery")        .IncludeFallback("window.jQuery", "~/Resource/Scripts/common/jquery-{version}.js")        .Production(ajaxCdnPath, "Scripts", "jquery.mincdn.js", "jquery.src.js"));

这样会生成如下的JS应用:

<script src="http://localhost/Cdn/Scripts/jquery.mincdn.js?00001"></script><script>(window.jQuery)||document.write('<script src="http://www.cnblogs.com//dome/bundles/jquery"><\/script>');</script>

这样的话当CDN站点挂掉了还是能够访问到JS文件的。

接下来CSS怎么处理呢:

StyleBundleExtensions.cs

 public static class StyleBundleExtensions  {    /// <summary>    /// Include a stylesheet to fallback to when external CdnPath does not load.    /// </summary>    /// <param name="bundle"></param>    /// <param name="fallback">Virtual path to fallback stylesheet</param>    /// <param name="className">Stylesheet class name applied to test DOM element</param>    /// <param name="ruleName">Rule name to test when the class is applied ie. width</param>    /// <param name="ruleValue">Value to test when the class is applied ie. 1px</param>    /// <returns></returns>    public static StyleBundle IncludeFallback(this StyleBundle bundle, string fallback,      string className = null, string ruleName = null, string ruleValue = null)    {      if (String.IsNullOrEmpty(bundle.CdnPath))      {        throw new Exception("CdnPath must be provided when specifying a fallback");      }      if (VirtualPathUtility.IsAppRelative(bundle.CdnPath))      {        bundle.CdnFallbackExpress(fallback);      }      else if (new[] { className, ruleName, ruleValue }.Any(String.IsNullOrEmpty))      {        throw new Exception(          "IncludeFallback for cross-domain CdnPath must provide values for parameters [className, ruleName, ruleValue].");      }      else      {        bundle.CdnFallbackExpress(fallback, className, ruleName, ruleValue);      }      return bundle;    }    private static StyleBundle CdnFallbackExpress(this StyleBundle bundle, string fallback,      string className = null, string ruleName = null, string ruleValue = null)    {      bundle.Include(fallback);      fallback = VirtualPathUtility.ToAbsolute(fallback);      bundle.CdnFallbackExpression = String.IsNullOrEmpty(className) ?        String.Format(@"function() {{        var len = document.styleSheets.length;        for (var i = 0; i < len; i++) {{          var sheet = document.styleSheets[i];          if (sheet.href.indexOf('{0}') !== -1) {{            var rules = sheet.rules || sheet.cssRules;            if (rules.length <= 0) {{              document.write('<link href=""{1}"" rel=""stylesheet"" type=""text/css"" />');            }}          }}        }}        return true;        }}()", bundle.CdnPath, fallback) :        String.Format(@"function() {{        var loadFallback,          len = document.styleSheets.length;        for (var i = 0; i < len; i++) {{          var sheet = document.styleSheets[i];          if (sheet.href.indexOf('{0}') !== -1) {{            var meta = document.createElement('meta');            meta.className = '{2}';            document.head.appendChild(meta);            var value = window.getComputedStyle(meta).getPropertyValue('{3}');            document.head.removeChild(meta);            if (value !== '{4}') {{              document.write('<link href=""{1}"" rel=""stylesheet"" type=""text/css"" />');            }}          }}        }}        return true;      }}()", bundle.CdnPath, fallback, className, ruleName, ruleValue);      return bundle;    }  }

 

好吧后面的大家自己摸索吧:)上班了
很多代码是网上抄袭的,东拼西凑。