用于开发和部署的静态资产和基于CDN的资产之间切换的最佳方式
我正在开发和ASP.NET MVC3中的应用程序。我计划利用亚马逊Cloudfront产品作为CDN服务于静态资产。用于开发和部署的静态资产和基于CDN的资产之间切换的最佳方式
我很好奇,如果有人设计了一种简单的方法来切换用于开发的本地资产和用于部署的基于CDN的资产?
任何提示或技巧将不胜感激。
同样保罗的回答。
在过去,我使用了UrlHelper的扩展方法,该方法根据web.config中的值创建链接。
这很有帮助,因此您不必在发布后微调视图,这与在发布时更新web.config条目一样简单。需要使用CDN资源的任何资源,你干脆说Url.CdnContent("~/site.css")
我不是在此刻我的开发PC,但是当我回家,我给你拿我的扩展方法源
这是非常简单的,但它的工作原理为我需要做的
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基本路径。
不错的问题。我建议你使用条件编译变量。
如果您的项目位于调试模式,则本地资产将被链接。如果您的项目处于发布模式,CDN资产将被链接。
这里有一个例子:
<head runat="server">
<% #if DEBUG %>
<link rel="stylesheet" type="text/css" href="/Assets/Styles/Default.css" />
<% #else %>
<link rel="stylesheet" type="text/css" href="http://cdn.mysite.com/Assets/Styles/Default.css" />
<% #endif %>
</head>
但要小心,当你发布你的项目,应该在释放模式。有一次,我更新了其中一个项目,它处于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
这看起来很直截了当。谢谢(你的)信息。我会检查出所有的链接 – stephen776 2012-02-20 20:54:05
@ stephen776:我很高兴它帮助:) – 2012-02-20 21:06:50
我有一组我使用(见下文)扩展方法。您可以使用这些作为基础/示例来创建您自己的自定义调试/版本扩展方法。
常规调试/释放:
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://mycdn.com/images/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(
"<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\" />",
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("<script type=\"text/javascript\" src=\"{0}\"></script>",
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)
这将是太棒了。谢谢。 – stephen776 2012-02-21 01:11:30
@ stephen776,如果您查看源代码,则使用扩展方法 – 2012-02-21 02:49:47
@ stephen776更新答案,它的设置也可以在没有web.config值的情况下运行。当我在本地开发时,我忽略了cdnroot appsetting,然后让我的web config在构建时添加它。 – 2012-02-21 19:47:05