13

我正在尝试使用此博客中描述的技术将嵌入式 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 优化框架时。按预期工作,VirtualPathProvider但它阻止IRouteHandler执行。如果FileExists方法更改为返回 false,这将允许 RouteHandler 执行,但显然会破坏VirtualPathProvider.

我假设它没有使用配置的路由,因为它在FileExists返回 true 时正在寻找物理文件?这是配置问题还是实现问题?

4

1 回答 1

12

您需要告诉 BundleTable 使用您的 VirtualPathProvider,如下所示:

BundleTable.VirtualPathProvider = new EmbeddedVirtualPathProvider(typeof(My.Custom.Type));

此功能是在Microsoft ASP.NET Web 优化框架 v1.1.0 中添加的。

此外,您需要通过将其添加到 web.config 来确保对 CSS 文件的请求通过 ASP.NET 管道。

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">

第二个问题可以通过设置RouteCollection.RouteExistingFiles来解决true

于 2015-02-14T13:59:26.460 回答