Лучший способ переключения между статическими активами и активами на основе CDN для разработки и развертывания - PullRequest
7 голосов
/ 20 февраля 2012

Я занимаюсь разработкой и применением в ASP.NET MVC3. Я планирую воспользоваться предложением Amazons Cloudfront в качестве CDN для обслуживания статических ресурсов.

Интересно, кто-нибудь изобрел простой метод переключения между локальными активами для разработки и активами на основе CDN для развертывания?

Любые советы или рекомендации будут с благодарностью.

Ответы [ 5 ]

7 голосов
/ 21 февраля 2012

Аналогично ответу Павла.

В прошлом я использовал метод расширения для 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;
}
4 голосов
/ 20 февраля 2012

Я делал это в прошлом, используя несколько простых правил:

  • Всегда используйте относительные пути к файлам в CSS
  • Всегда используйте стандартный шаблон для ссылки на контент в ваших представлениях(Я использую относительные пути приложения с Url.Content, т.е. Url.Content("~/content/file.jpg"))
  • Не ссылаться на файлы в JavaScript.

Тогда в моем процессе развертывания я могу просто скопировать все статическиеРесурсы с сайта на CDN, CSS будет просто работать, так как его относительный (значения CSS url() всегда относятся к файлу CSS, в котором они находятся, а не к запросу), и я буду использовать регулярное выражение для замены любых строк в моих представленияхв той форме, в которой я ожидаю базовый путь CDN.

2 голосов
/ 20 февраля 2012

Хороший вопрос .Я предлагаю вам использовать Условные переменные компиляции .

Если ваш проект находится в режиме отладки , локальные ресурсы будут связаны.Если ваш проект находится в режиме выпуска , ресурсы 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>

Но будьте осторожны, когда вы публикуете Вы проецируете , он должен быть в режиме выпуска .Однажды я обновил один из своих проектов, и он был в режиме отладки, и все пошло не так.

Вот несколько хороших ссылок о условной компиляции:

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

1 голос
/ 21 февраля 2012

Я специально разработал библиотеку для решения этой проблемы.

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

1 голос
/ 21 февраля 2012

У меня есть набор методов расширения, которые я использую (см. Ниже). Вы можете использовать их как основу / пример для создания собственных методов расширения отладки / выпуска.

Общая отладка / выпуск:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...