私はいくつかの静的ファイル (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 だけで静的ファイルを提供できますか?
更新: 更新されたディレクトリ構造