在静态资产和基于CDN的资产之间切换以进行开发和部署的最佳方法

我正在ASP.NET MVC3中开发和应用程序。 我计划利用亚马逊Cloudfront产品作为CDN来提供静态资产。

我很好奇是否有人设计了一种简单的方法来切换用于开发的本地资产和用于部署的基于CDN的资产?

任何提示或技巧将不胜感激。

与保罗的回答相似。

在过去,我使用了UrlHelper的扩展方法,该方法根据web.config中的值创建链接。

这很有用,因此您不必在发布后对视图进行微观处理,就像在发布时更新web.config条目一样简单。 任何需要使用CDN资源的资源,你只需说Url.CdnContent("~/site.css")

我现在不在我的开发电脑上,但是当我回到家时,我会告诉你扩展方法的来源

它非常简单,但它适用于我需要它做的事情

 public static string CdnContent(this UrlHelper helper, string relativePath) { var cdnRoot = ConfigurationManager.AppSettings["cygnus.cdnroot"]; if (string.IsNullOrEmpty(cdnRoot)) return UrlHelper.GenerateContentUrl(relativePath, helper.RequestContext.HttpContext); if (relativePath.StartsWith("~")) relativePath = relativePath.Substring(1); if (cdnRoot.EndsWith("/")) cdnRoot = cdnRoot.Substring(0, cdnRoot.Length - 1); if (!relativePath.StartsWith("/")) relativePath = "/" + relativePath; return cdnRoot + relativePath; } 

我过去使用一些简单的规则完成了它:

  • 始终在CSS中使用文件相对路径
  • 始终使用标准模式来引用视图中的内容(我使用Url.Content应用程序相对路径,即Url.Content("~/content/file.jpg")
  • 不要在JavaScript中引用文件。

然后在我的部署过程中,我可以简单地将所有静态资产从站点复制到CDN,CSS将起作用,因为它的相对(CSS url()值总是相对于它们所在的CSS文件,而不是请求),以及我将使用正则表达式来替换我希望具有CDN基本路径的forms的视图中的任何字符串。

好问题 。 我建议你使用条件编译变量

如果项目处于调试模式 ,则会链接本地资产。 如果您的项目处于发布模式 ,则会链接CDN资产。

这是一个示例:

  <% #if DEBUG %>  <% #else %>  <% #endif %>  

但要小心,当您发布项目时 ,它应该处于发布模式 。 有一次,我更新了我的一个项目,它处于DEBUG模式,一切都出错了。

以下是有关条件编译的一些很好的链接:

http://haacked.com/archive/2007/09/16/conditional-compilation-constants-and-asp.net.aspx

http://odetocode.com/blogs/scott/archive/2005/12/01/conditional-compilation-in-asp-net-2-0.aspx

http://odetocode.com/blogs/scott/archive/2007/09/24/more-on-conditional-compilation-in-asp-net.aspx

我有一套我使用的扩展方法(见下文)。 您可以使用它们作为基础/示例来创建自己的自定义调试/发布扩展方法。

一般调试/发布:

 public static MvcHtmlString DebugReleaseString(this System.Web.Mvc.HtmlHelper html, string debugString, string releaseString) { string toReturn = debugString; #if !DEBUG if (!string.IsNullOrEmpty(releaseString)) toReturn = releaseString; #endif return MvcHtmlString.Create(toReturn); } 

一般调试/发布用法:

 @Html.DebugReleaseString("/images/myimage.jpg", "http://sofzh.miximages.com/c%23/myimage.jpg") 

调试/发布CSS标签:

 public static MvcHtmlString CssTag(this System.Web.Mvc.HtmlHelper html, string fileName) { return html.CssTag(fileName, string.Empty); } public static MvcHtmlString CssTag(this System.Web.Mvc.HtmlHelper html, string fileName, string releaseFileName) { if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName"); string cssTag = string.Format( "", html.MeDebugReleaseString(fileName, releaseFileName)); return MvcHtmlString.Create(cssTag); } 

调试/发布CSS标签用法:

 @Html.CssTag("/styles/mystyle.css") @Html.CssTag("/styles/mystyle.css", "http://mycdn.com/styles/mystyle.css") 

调试/发布JS标签:

 public static MvcHtmlString JavascriptTag(this System.Web.Mvc.HtmlHelper html, string fileName) { return html.JavascriptTag(fileName, string.Empty); } public static MvcHtmlString JavascriptTag(this System.Web.Mvc.HtmlHelper html, string fileName, string releaseFileName) { if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName"); string jsTag = string.Format("", html.MeDebugReleaseString(fileName, releaseFileName)); return MvcHtmlString.Create(jsTag); } 

调试/发布JS标签用法:

 @Html.JavascriptTag("/scripts/myscript.css") @Html.JavascriptTag("/scripts/myscript.css", "http://mycdn.com/scripts/myscript.js") 

其他调试/发布选项:

 public enum RenderModeEnum { Debug, Release, DebugAndRelease } public static MvcHtmlString CssTag(this System.Web.Mvc.HtmlHelper html, string fileName, RenderModeEnum tagRenderMode) { if (tagRenderMode == RenderModeEnum.DebugAndRelease) return html.CssTag(fileName); #if DEBUG if (tagRenderMode == RenderModeEnum.Debug) return html.CssTag(fileName); #else if (tagRenderMode == RenderModeEnum.Release) return html.CssTag(fileName); #endif return MvcHtmlString.Empty; } public static MvcHtmlString JavascriptTag(this System.Web.Mvc.HtmlHelper html, string fileName, RenderModeEnum tagRenderMode) { if (tagRenderMode == RenderModeEnum.DebugAndRelease) return html.JavascriptTag(fileName); #if DEBUG if (tagRenderMode == RenderModeEnum.Debug) return html.JavascriptTag(fileName); #else if (tagRenderMode == RenderModeEnum.Release) return html.JavascriptTag(fileName); #endif return MvcHtmlString.Empty; } 

其他调试/发布选项用法:

 @Html.CssTag("/styles/mystyle.css", RenderModeEnum.DebugAndRelease) @Html.CssTag("/styles/mystyle.css", RenderModeEnum.Debug) @Html.CssTag("http://mycdn.com/styles/mystyle.css", RenderModeEnum.Release) 

我专门开发了一个库来解决这个问题。

https://github.com/vincpa/mvc.resourceloader