Получить доступ к URL-адресу, используемому в System.Web.Optimization
Предыстория: я использую кэш автономного приложения HTML 5 и динамически создаю файл манифеста. По сути, файл манифеста должен содержать список всех статических файлов, которые запрашивает ваша страница. Прекрасно работает, когда файлы на самом деле статичны, но я использую Bundling and Minification в System.Web.Optimization
, так что мои файлы не являются статичными.
Когда в символе DEBUG загружен (т.е. отладка в VS), то фактические физические файлы вызываются из MVC View. Однако в режиме Release он вызывает виртуальный файл, который может выглядеть примерно так: /bundles/scripts/jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1
Итак, мой вопрос: как я могу получить этот URL в коде, чтобы добавить его в манифест автономного приложения?
Я пробовал:
var paths = new List<string>()
{
"~/bundles/styles/common",
"~/bundles/styles/common1024",
"~/bundles/styles/common768",
"~/bundles/styles/common480",
"~/bundles/styles/frontend",
"~/bundles/scripts/jquery",
"~/bundles/scripts/common",
"~/bundles/scripts/frontend"
};
var bundleTable = BundleTable.Bundles;
foreach (var bundle in bundleTable.Where(b => paths.Contains(b.Path)))
{
var bundleContext = new BundleContext(this.HttpContext, bundleTable, bundle.Path);
IEnumerable<BundleFile> files = bundle.GenerateBundleResponse(bundleContext).Files;
foreach (var file in files)
{
var filePath = file.IncludedVirtualPath.TrimStart(new[] { '~' });
sb.AppendFormat(formatFullDomain, filePath);
}
}
Как и замена GenerateBundleResponse()
с EnumerateFiles()
, но он всегда возвращает исходные пути к файлам.
Я также открыт для альтернативных предложений по реализации. Благодарю.
ОБНОВЛЕНИЕ: (7/7/14 13:45)
Помимо ответа ниже, я также добавил этот класс реестра Bundles, чтобы сохранить список необходимых статических файлов, чтобы он работал в режиме отладки во всех браузерах. (См. Комментарии ниже)
public class Registry
{
public bool Debug = false;
public Registry()
{
SetDebug();
}
[Conditional("DEBUG")]
private void SetDebug()
{
Debug = true;
}
public IEnumerable<string> CommonScripts
{
get
{
if (Debug)
{
return new string[]{
"/scripts/common/jquery.validate.js",
"/scripts/common/jquery.validate.unobtrusive.js",
"/scripts/common/knockout-3.1.0.debug.js",
"/scripts/common/jquery.timepicker.js",
"/scripts/common/datepicker.js",
"/scripts/common/utils.js",
"/scripts/common/jquery.minicolors.js",
"/scripts/common/chosen.jquery.custom.js"
};
}
else
{
return new string[]{
"/scripts/common/commonbundle.js"
};
}
}
}
}
Я ни в коем случае не доволен этим решением. Пожалуйста, сделайте предложения, если вы можете улучшить это.
1 ответ
Я могу предложить альтернативу из этого поста в блоге создать свой собственный токен.
Таким образом, автор предлагает использовать веб-основы для создания связанного файла, а затем создать вспомогательный инструмент для генерации токена, в данном случае на основе последних измененных даты и времени.
public static class StaticFile
{
public static string Version(string rootRelativePath)
{
if (HttpRuntime.Cache[rootRelativePath] == null)
{
var absolutePath = HostingEnvironment.MapPath(rootRelativePath);
var lastChangedDateTime = File.GetLastWriteTime(absolutePath);
if (rootRelativePath.StartsWith("~"))
{
rootRelativePath = rootRelativePath.Substring(1);
}
var versionedUrl = rootRelativePath + "?v=" + lastChangedDateTime.Ticks;
HttpRuntime.Cache.Insert(rootRelativePath, versionedUrl, new CacheDependency(absolutePath));
}
return HttpRuntime.Cache[rootRelativePath] as string;
}
}
Тогда вы можете ссылаться на файл в комплекте, как это...
@section scripts {
<script src="@StaticFile.Version("~/Scripts/app/myAppBundle.min.js")"></script>}
Тогда вы можете контролировать токен и можете делать с ним все, что хотите.