Объединение/минимизация ASP.NET и встроенные ресурсы
Я пытаюсь использовать технику, описанную в в этом блоге, чтобы добавить встроенные ресурсы dll в мои пакеты.
Я создал пользовательский VirtualPathProvider
ниже.
public class EmbeddedVirtualPathProvider : VirtualPathProvider {
private Type _rootType;
public EmbeddedVirtualPathProvider(Type rootType) {
_rootType = rootType;
}
public override bool FileExists(string virtualPath) {
if (IsEmbeddedPath(virtualPath))
return true;
else
return Previous.FileExists(virtualPath);
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) {
if (IsEmbeddedPath(virtualPath)) {
return null;
}
else {
return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
}
public override VirtualDirectory GetDirectory(string virtualDir) {
return Previous.GetDirectory(virtualDir);
}
public override bool DirectoryExists(string virtualDir) {
return Previous.DirectoryExists(virtualDir);
}
public override VirtualFile GetFile(string virtualPath) {
if (IsEmbeddedPath(virtualPath)) {
string fileNameWithExtension = virtualPath.Substring(virtualPath.LastIndexOf("/") + 1);
string nameSpace = _rootType.Namespace;
string manifestResourceName = String.Format("{0}.{1}", nameSpace, fileNameWithExtension);
var stream = _rootType.Assembly.GetManifestResourceStream(manifestResourceName);
return new EmbeddedVirtualFile(virtualPath, stream);
}
else
return Previous.GetFile(virtualPath);
}
private bool IsEmbeddedPath(string path) {
return path.Contains("~/Embedded");
}
}
public class EmbeddedVirtualFile : VirtualFile {
private Stream _stream;
public EmbeddedVirtualFile(string virtualPath, Stream stream)
: base(virtualPath) {
_stream = stream;
}
public override Stream Open() {
return _stream;
}
}
Затем зарегистрирую это и настрою пакеты;
public static void RegisterBundles(BundleCollection bundles) {
HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedVirtualPathProvider(typeof(My.Custom.Type)));
bundles.Add(new StyleBundle("~/Embedded/css").Include(
"~/Embedded/files/styles/etc/styles.css")
);
}
Я также внедрил пользовательский EmbeddedResourceHttpHandler
, как описано в статье, которая работает при запросе файла как прямой HTTP-запрос.
Проблема:
Вложенные файлы не включаются в комплект, они просто игнорируются. Когда отладка метода FileExists
вызывается несколько раз, но никогда для ~/Embedded/files/styles/etc/styles.css
Что мне не хватает?
Дополнительная проблема
При использовании последней версии Microsoft ASP.NET Web Optimization Framework. VirtualPathProvider
работает так, как ожидалось, однако это предотвращает выполнение IRouteHandler
. Если метод FileExists
изменен для возврата false, это позволяет выполнить RouteHandler, но, очевидно, нарушает VirtualPathProvider
.
Я предполагаю, что он не использует настроенный маршрут, потому что он ищет физический файл, когда FileExists
возвращает true? Это проблема конфигурации или реализации?
Ответы
Ответ 1
Вам нужно будет сообщить BundleTable, чтобы использовать ваш VirtualPathProvider следующим образом:
BundleTable.VirtualPathProvider = new EmbeddedVirtualPathProvider(typeof(My.Custom.Type));
Эта функциональность была добавлена в v1.1.0 Структуры веб-оптимизации Microsoft ASP.NET.
Также вам нужно убедиться, что запросы на файл CSS проходят через конвейер ASP.NET, добавив это в ваш web.config.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
Вторую проблему можно решить, установив RouteCollection.RouteExistingFiles
в true