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 Optimization Framework の最新バージョンを使用している場合。はVirtualPathProvider期待どおりに動作しますがIRouteHandler、実行できません。メソッドが false を返すように変更された場合、FileExistsこれにより RouteHandler を実行できますが、明らかにVirtualPathProvider.

FileExiststrueが返されたときに物理ファイルを探しているため、構成されたルートを使用していないと思いますか? これは構成または実装の問題ですか?

4

1 に答える 1

12

次のように、VirtualPathProvider を使用するように BundleTable に指示する必要があります。

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

この機能は、Microsoft ASP.NET Web Optimization Framework の v1.1.0 で追加されました。

また、これを web.config に追加して、CSS ファイルの要求が ASP.NET パイプラインを通過するようにする必要があります。

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

RouteCollection.RouteExistingFiles二次的な問題は、に設定することで解決できますtrue

于 2015-02-14T13:59:26.460 に答える