Эд Планкетт,
Если вы используете это как HTML помощник HttpContextBase
могут быть захвачены из ViewContext.HttpContext
собственности. Это может быть создано, например.
public static IHtmlString BundleCss(this HtmlHelper html, string outputPath, params string[] cssFilePaths)
{
var collection = new BundleCollection();
foreach (var cssFilePath in cssFilePaths)
collection.Add(new Bundle(cssFilePath));
var bundler = new BundleContext(html.ViewContext.HttpContext, collection, outputPath);
//... ommitted code
System.Web.Optimization.CssMinify minify = new CssMinify();
minify.Process(bundler, response);
//... TODO: Grab the response content and return
}
Да, это базовый пример использования HTML-помощника. Дайте мне знать, если это не ответит на ваш вопрос.
EDIT: После повторного чтения вопроса я уточняю свой ответ. Таким образом, вышеупомянутое помогает найти свойство HttpContextBase
. Однако я думаю, что вопрос заключается в том, как вы можете действительно читать содержимое файлов, их минимизировать и помещать в тег <style>
на странице.
я принял удар на написание моей собственной интерпретации вашего требования и придумал следующий набор классов
Мой CssOutputBundler класс:
public class CssOutputBundler
{
static readonly Dictionary<string, string> cachedOutput = new Dictionary<string, string>();
readonly string tempFileOutputPath;
readonly HtmlHelper helper;
readonly IList<string> virtualFilePaths;
public CssOutputBundler(HtmlHelper helper, string tempFileOutputPath)
{
if (helper == null)
throw new ArgumentNullException("helper null");
if (string.IsNullOrWhiteSpace(tempFileOutputPath))
this.tempFileOutputPath = tempFileOutputPath;
this.helper = helper;
this.virtualFilePaths = new List<string>();
this.tempFileOutputPath = tempFileOutputPath;
}
public CssOutputBundler Add(string cssFilePath)
{
if (!this.virtualFilePaths.Contains(cssFilePath))
this.virtualFilePaths.Add(cssFilePath);
return this;
}
public IHtmlString Minify()
{
if (helper == null)
throw new ArgumentNullException("helper null");
string cache_string = string.Join(",", this.virtualFilePaths);
if(cachedOutput.ContainsKey(cache_string))
return formatResponse(File.ReadAllText(cachedOutput[cache_string]));
var bundle = new StyleBundle(this.tempFileOutputPath).Include(this.virtualFilePaths.ToArray());
var collection = new BundleCollection();
collection.Add(bundle);
var context = new BundleContext(helper.ViewContext.HttpContext, collection, "");
var response = bundle.GenerateBundleResponse(context);
System.Web.Optimization.CssMinify minify = new CssMinify();
minify.Process(context, response);
string serverPath = helper.ViewContext.HttpContext.Server.MapPath(this.tempFileOutputPath);
string outputPath = Guid.NewGuid().ToString() + ".css";
while(File.Exists(Path.Combine(serverPath, outputPath)))
outputPath = Guid.NewGuid().ToString() + ".css";
File.WriteAllText(outputPath, response.Content);
cachedOutput[cache_string] = outputPath;
return formatResponse(response.Content);
}
IHtmlString formatResponse(string responseContent)
{
StringBuilder responseBuilder = new StringBuilder();
responseBuilder.AppendLine("<style type=\"text/css\">");
responseBuilder.Append(responseContent);
responseBuilder.AppendLine("</style>");
return helper.Raw(responseBuilder.ToString());
}
}
Ok выше класс выглядит сложным, но все это делает создает внутренний список путей для связывания пакетов и их минимизации. Когда вызывается метод Minify, он форматирует виртуальные пути в строку, которая используется как ключ кеша . Вот как мы определяем, были ли мы уже связаны и минимизировали эти сценарии.
Если у нас есть, мы читаем временный вложенный скрипт, который хранится на жестком диске.
Примечание:Я использовал хранилище на жестком диске, а не в памяти. Это можно легко изменить, набив полный контент в статический словарь или другой ресурс для кеширования.
Если этот набор файлов не был в комплекте, миниатюрный и т. Д., То мы переходим к пакету и минимизируем набор. Наконец, мы храним файл на HDD и возвращаем ответ. Так что это довольно легко.
Теперь, чтобы реализовать класс, я просто написал быстрый HTML-помощник, так как класс Minits поддерживает цепочки для Add
. Файлы могут быть реализованы красиво.
HTML-Helper:
public static CssOutputBundler BundleCss(this HtmlHelper helper, string outputVirtualPath)
{
return new CssOutputBundler(helper, outputVirtualPath);
}
Ok базовая реализация для пакетирования. Теперь этот помощник принимает строку outputVirtualPath
, это виртуальный PATH для хранения временных файлов. Если вы решите устранить сохранение на HDD и использовать систему кеша, вы можете удалить этот параметр из помощника и класса.
Наконец, это может быть использовано в вашей точке зрения, как ...
@Html.BundleCss("~/Content/").Add("~/Content/Site.css").Add("~/Content/themes/base/jquery-ui.css").Minify();
Где ~/Content/
это виртуальный путь на жестком диске для хранения файлов минимизированы. Затем добавим два файла: "~/Content/Site.css"
и ~/Content/themes/base/jquery-ui.css
. Наконец вызовите метод minify, который возвращает строку html. Такие как ...
<style type="text/css">
.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)} ....more css
</style>
Cheers.
Быстрое примечание: вы можете получить экземпляр «HttpContextBase» без труда: 'new HttpContextWrapper (HttpContext.Current)' (или вставить рамки DI по вашему выбору, чтобы избежать жесткого кодирования зависимости). –