3

私はいくつかの静的ファイル (css、画像、スクリプト) といくつかのビューを別のライブラリからいくつかの MVC アプリケーションに共有しようとしています。これが私のディレクトリ構造です:

Solution
   Directory 1
      MyContent
        css
          site.css
        images
          img.png
      MyViews
         Account
           Login.cshtml
   Directory 2
      MVCApp1
   Directory 3
      MVCApp2

これが私の ResolveVppPath メソッドです。

public static string ResolveVppPath(string path)
{
    // path before looks like ex. ~/shared/content/css/site.css

    path = path.ToLower().Replace("~/shared/","~/my");
    var vp = Path.GetFullPath(Path.Combine(HostingEnvironment.MapPath("~"), "../" + path)); 

    // returns full path + ...  /mycontent/css/site.css ...
    return vp;
}

public static string ResolveSharedControllerPath(string path)
{

        // path before looks like, "~/shared" is ommited in by routing ex. /content/css/site.css

        path = "/my" + path.ToLower().TrimStart(new char[]{'/'})
        var vp = Path.GetFullPath(Path.Combine(HostingEnvironment.MapPath("~"), "../" + path)); 

        // returns full path + ...  /mycontent/css/site.css ...
        return vp;
    }

元のアイデアは、アプリごとに 1 つのコントローラーが継承される抽象コントローラーを作成することでした。これは、パスを解決し、dll から静的ファイルを返すために使用されました。すべてが機能しましたが、ファイルが物理的ではないため、バンドルを使用できませんでした。

アプリごとに 1 回継承する抽象コントローラー:

public FilesController : Controller
{
    public ActionResult(string path)
        {
       var vp = ResolveSharedControllerPath(path);
           return File(path, MethodToGetMIMEType(path));
    }
}

アプリごとに 1 回:

public SharedController : FilesController {}

ルート:

routes.MapRoute(
    "Shared",
    "shared/{*path}",
    new { controller = "Files", action = "Index" }
    );

そして、System.Web.Optimization の新しいベータ リリースが VirtualPathProvider からのバンドルをサポートしていることを知りました (初めて耳にしました)。そこで、VPP を継承するクラスと VirtualFile を継承するクラスの 2 つのクラスを作成しました。

コードは長すぎますが、要するに、私は物理ファイルを実装するのが簡単だったので、私の Exists() オーバーライドは File.Exist を呼び出すだけで、Open はそれをストリームとして開くだけなので、次のように設定しました:

BundleTable.VirtualPathProvider = new SharedVirtualPathProvider();

バンドルが機能し始め、css とスクリプトをレンダリングするようになりました。

しかし、ファイルを提供するために作成したControllerからファイルがフェッチされているように感じたので、ファイルを提供するControllerとVirtualPathProviderの両方を持つのは意味がなかったので、それを削除してルートを共有しました。コントローラ バンドルを削除した後、動作が停止し、firebug 20 の見つからないリクエストで確認できたので、VPP にブレークポイントを配置して、それが呼び出されているかどうかを確認しました。VPP で FileExists メソッドと呼ばれ、正しいパスと Open で GetFile が呼び出されていることを明確に確認できました。 . しかし、この静的リソースはブラウザーからは利用できませんでした。

そこで、静的拡張子を持つファイルに IgnoreRoutes を配置することにしました。

{file}.css
{file}.js
...etc

運が悪い...

それは何もしなかったので、ファイルを提供するためにコントローラーとルートエイジアンを含めました。すべてが再び機能し始めました。

次のステップは、いくつかのビューを DLL に移動することでした。ビューを切り取り、MyViewsDLL に貼り付けましたが、「@model ..」の最初の行で firefox の XML 解析エラーが発生し、さらに、これは必要ないため機能しませんでした。ビューのレンダリングされていないコードを人々に見てもらいます。また、エンジンがビューを探すパスをオーバーライドするカスタム ViewEngine を実装する必要がありました。

"~/Shared/views/{1}/{0}

パスに追加し、ViewEngineをglobal.asaxのViewEnginesコレクションに追加しました

私の質問は:

VPS ホスティングを使用しています (IIS を完全に制御できます)。ファイルのアプリケーションからフォルダー (および DLL フォルダー) に移動しようとすると問題が発生しますか?

静的ファイルを返すために、VPP と Controller の両方が本当に必要ですか?

DLL からビューを取得し、ブラウザーからビューを取得して、誰でもビューを表示できるようにするにはどうすればよいですか?

VPP だけで静的ファイルを提供できますか?

更新: 更新されたディレクトリ構造

4

1 に答える 1

4

私の EmbeddedResourceVirtualPathProvider がお手伝いします。一部またはすべての静的ファイルとビューを他のプロジェクトに含めることができます。

http://nuget.org/packages/EmbeddedResourceVirtualPathProvider/

コントローラーは必要ありません。VPP といくつかのマッピング (Nuget パッケージによって web.config で設定されます) で十分です。

編集: Bundler でテストしていませんが、動作しない理由がわかりません。

于 2013-05-23T12:56:14.590 に答える