Добавить URL-адрес CDN к выходным данным сборщика mvc 4

Используя встроенный упаковщик MVC4, как мне добавить URL-адрес CDN к тегам ссылок, которые он создает? Я настроил Amazon Cloudfront таким образом, чтобы он извлекал ресурсы с моего веб-сервера при первом запросе. Поэтому, когда я определяю пакет следующим образом:

 bundles.Add(new StyleBundle("~/Content/css").Include(
    "~/Content/reset.css",
    "~/Content/960_24_col.css",
    "~/Content/Site.css"
 ));

При развертывании я могу ссылаться на него следующим образом:

http://[cloundfrontid].cloudfront.net/Content/css?v=muhFMZ4thy_XV3dMI2kPt-8Rljm5PNW0tHeDkvenT0g1

Теперь мне просто нужно изменить ссылки, созданные упаковщиком, с относительных на абсолютные ссылки, указывающие на мой CDN.

  <link href="[INSERT_CDN_URL_HERE]/Content/css?v=muhFMZ4thy_XV3dMI2kPt-8Rljm5PNW0tHeDkvenT0g1" rel="stylesheet"/>

Я думаю, что можно переписать путь с помощью IBundleTransform, но я не могу найти никаких примеров этого.

ПРИМЕЧАНИЕ. Для ясности: я знаю, что вы можете указать ссылку CDN для пакета, но это работает только в том случае, если пакет можно заменить статической ссылкой.


person PeteG    schedule 12.02.2013    source источник
comment
Почему вы не можете использовать статическую ссылку на свой CDN?   -  person Hao Kung    schedule 15.02.2013
comment
потому что я не знаю, какой будет эта ссылка во время компиляции. Упаковщик назначает его динамически с помощью строки очистки кеша, например. /Content/css?v=muhFMZ4thy_XV3dMI2kPt-8Rljm5PNW0tHeDkvenT0g1   -  person PeteG    schedule 15.02.2013
comment
Ваш CDN фактически использует строку запроса, чтобы включить, какой контент он возвращает? Не могли бы вы просто жестко закодировать версии в свой CDN? то есть /content/css1 и просто поднимать его каждый раз, когда вы обновляете свои пакеты?   -  person Hao Kung    schedule 15.02.2013
comment
Я понимаю, что вы говорите: контролируйте перебор кеша, вручную устанавливая строку запроса. Имеет смысл. В идеале я хотел бы полностью автоматизировать процесс развертывания, так как это то, что я бы забыл увеличить.   -  person PeteG    schedule 18.02.2013


Ответы (2)


Я только что установил MaxCDN и столкнулся с той же проблемой.

Как вы знаете, свойство bundles.UseCdn не идеально, поскольку нам не нужно указывать точный URL-адрес пакета. CDN, такой как Max CDN, представляет собой точно такой же URL-адрес, строку запроса и все остальное, за исключением другого поддомена.

Вот как я решил это.

Я создал класс BundleHelper, который будет обертывать метод рендеринга, а затем добавлять путь к поддомену CDN.

Вот как выглядит класс:

namespace MyDomain.Web.Helpers
{
    public class BundleHelper
    {
        public static string CdnPath = "http://cdn.mydomain.com";

        public static IHtmlString RenderScript(string path)
        {
            var opt = System.Web.Optimization.Scripts.Render(path);
            string htmlString = HttpUtility.HtmlDecode(opt.ToHtmlString());

            if (BundleTable.EnableOptimizations)
            {
                htmlString = htmlString.Replace("<script src=\"/", String.Format("<script src=\"{0}/", CdnPath));
            }

            return new HtmlString(htmlString);
        }

        public static IHtmlString RenderStyle(string path)
        {
            var opt = System.Web.Optimization.Styles.Render(path);
            string htmlString = HttpUtility.HtmlDecode(opt.ToHtmlString());

            if (BundleTable.EnableOptimizations)
            {
                htmlString = htmlString.Replace("<link href=\"/", String.Format("<link href=\"{0}/", CdnPath));
            }

            return new HtmlString(htmlString);
        }
    }
}

Затем, чтобы использовать его в представлениях, я просто делаю:

@BundleHelper.RenderStyle("~/Content/css")
@BundleHelper.RenderStyle("~/Content/themes/base/css")

@BundleHelper.RenderScript("~/bundles/jquery")
@BundleHelper.RenderScript("~/bundles/jqueryui")

Надеюсь это поможет.

person BigJoe714    schedule 11.06.2013
comment
Я не пробовал, но это похоже на хорошее решение. В конце концов я выбрал решение, описанное в моем блоге. Я отмечу ваш как принятый, потому что он более эффективен. - person PeteG; 13.06.2013
comment
Здравствуйте, BigJoe: я также хочу добавить URL-адрес cdn к выходным данным сборщика... и я сделал то же, что вы описали, я не понял, что вы сделали в ViewPages. Не могли бы вы объяснить? - person Ankita; 07.10.2014

Посмотрите @ Использование CDN и найдите " Использование CDN"

Как сказал Рик Андерсон в asp.net/mvc,

Следующий код заменяет локальный пакет jQuery пакетом CDN jQuery.

    public static void RegisterBundles(BundleCollection bundles)
    {
    //bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
    //            "~/Scripts/jquery-{version}.js"));

    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"));

    // Code removed for clarity.
    }

В приведенном выше коде jQuery будет запрашиваться из CDN в режиме выпуска, а отладочная версия jQuery будет загружаться локально в режиме отладки. При использовании CDN у вас должен быть резервный механизм на случай сбоя запроса CDN. Следующий фрагмент разметки в конце файла макета показывает скрипт, добавленный для запроса jQuery в случае сбоя CDN.

    </footer>

        @Scripts.Render("~/bundles/jquery")

        <script type="text/javascript">
            if (typeof jQuery == 'undefined') {
                var e = document.createElement('script');
                e.src = '@Url.Content("~/Scripts/jquery-1.7.1.js")';
                e.type = 'text/javascript';
                document.getElementsByTagName("head")[0].appendChild(e);

            }
        </script> 

        @RenderSection("scripts", required: false)
    </body>
</html>

Я вставил раздел с Asp.net/MVC, если вы сочтете его полезным, то ура Рику Андерсону за его пост...

person Shubh    schedule 22.03.2013
comment
Ой, пост от 12 февраля :) - person Shubh; 23.03.2013