Дружим System.Web.Optimization Bundle с Windows Azure Storage

от автора

Я все ждал, ждал, ждал, когда же все-таки умные ребята, разрабатывающие System.Web.Optimization добавят поддержку автоматической загрузки содержимого бандла в контейнер Azure Storage. На днях вышла «1.0.0-beta2», но желаемого функционала так я и не нашел, а быстроты то хочется…

Как использовать?

<head>     @BlobStorageProvider.Render("~/mainlayout", BlobStorageProvider.ContentType.Style) </head> 

Как работает?

/// <summary> /// Ссылка на кеш-хранилище Blob'а /// </summary> private const string CachedStorageLink = "http://cdn.m6lab.com/{0}/{1}"; 

В вышеприведенном коде указана ссылка на привязанный Caching к Blob’у. Скорость отклика у Blob’а оставляет желать лучшего, поэтому рекомендую использовать Caching для получения данных из Blob’а.

Сделать override на функцию, создающую Bundle не представляется возможным, поэтому пришлось использовать костыль:

// Данные файла на сервере var content = new WebClient().DownloadString("{URL Вашего сайта}" + url); 

Исходный код целиком:

public class BlobStorageProvider {     /// <summary>     /// Перечисление возможных типов загружаемого контента     /// </summary>     public enum ContentType {         Script,         Style     }      /// <summary>     /// Ссылка на кеш-хранилище Blob'а     /// </summary>     private const string CachedStorageLink = "http://cdn.m6lab.com/{0}/{1}";      /// <summary>     /// Название Blob-хранилища     /// </summary>     private const string ContainerName = "robofollower";      /// <summary>     /// Настройки подключения к Blob'у     /// </summary>     private static readonly CloudStorageAccount StorageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName={Storage Account};AccountKey={Primary Key}");      /// <summary>     /// Контейнер Blob'a     /// </summary>     private static readonly CloudBlobContainer Container = StorageAccount.CreateCloudBlobClient().GetContainerReference(ContainerName);      /// <summary>     /// Контейнер ссылок на CDN     /// </summary>     private static readonly Dictionary<string, string> CdnLinks = new Dictionary<string, string>();      /// <summary>     /// Загруза данных в Blob-контейнер     /// </summary>     /// <param name="virtualPath"></param>     /// <param name="contentType"></param>     /// <returns></returns>     private static void Upload(string virtualPath, ContentType contentType) {         // Ссылка на файл на сервере         var url = Scripts.Url(virtualPath);         // Данные файла на сервере         var content = new WebClient().DownloadString("{URL Вашего сайта}" + url);         // Удаляем лишние знаки         var formatted = url.ToString().Replace("/", "").Replace("?", "").Replace("v", "").Replace("=", "").Replace("-", "");          var blobContentType = string.Empty;         // Добавляем постфикс и настраиваем контейнер         switch (contentType) {             case ContentType.Script:                 formatted += ".js";                 blobContentType = "text/javascript";                 break;              case ContentType.Style:                 formatted += ".css";                 blobContentType = "text/css";                 break;         }          // Референс блоба и его настройки         var blob = Container.GetBlockBlobReference(formatted);         blob.Properties.CacheControl = "public, max-age=3600";         blob.Properties.ContentType = blobContentType;          // Загрузка в контейнер         blob.UploadFromStream(new MemoryStream(Encoding.ASCII.GetBytes(content)));          // Добавляем в локальный контейнер ссылку         CdnLinks.Add(virtualPath, string.Format(CachedStorageLink, ContainerName, formatted));     }      public static IHtmlString Render(string virtualPath, ContentType contentType) {          if (!CdnLinks.ContainsKey(virtualPath))             Upload(virtualPath, contentType);          switch (contentType) {             case ContentType.Style: {                     var tag = new TagBuilder("link");                     tag.MergeAttributes(new Dictionary<string, string> { { "href", CdnLinks[virtualPath] }, { "rel", "stylesheet" } });                     return new HtmlString(tag.ToString(TagRenderMode.SelfClosing));                 }             case ContentType.Script: {                     var tag = new TagBuilder("script");                     tag.MergeAttributes(new Dictionary<string, string> { { "src", CdnLinks[virtualPath] } });                     return new HtmlString(tag.ToString(TagRenderMode.SelfClosing));                 }         }          return null;     } }

ссылка на оригинал статьи http://habrahabr.ru/post/157597/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *