私は別のクラスライブラリでコンパイル済みの剃刀ビューをMVC3のプラグインシステムの一種として使用しています。MVC3 - コンパイル済みの剃刀ビューで_ViewStartを見つけることができません
私はChris Van De Steed hereのガイドに従っていますが、実行時にアセンブリを読み込んでいるので、参照の追加について主に部分的に逸脱しています。
実行時にアセンブリを読み込むので、私はBoCライブラリでVirtualPathProviderViewEngineを使用せず、代わりにRazorViewEngineに基づく独自のViewEngineを実装しました。これは、ビューを解決できるように適切な名前空間を挿入するために、CreateViewのviewPathを書き換えることによって機能します。
これまでのところ非常に優れています...異なるモジュールが読み込まれている可能性があり、コントローラが同じ名前を共有する場合、コントローラは衝突しません。
私が今抱えている唯一の問題は、コンパイルされたビューでは_ViewStartが呼び出されないことです。 _ViewStartはホストMVC3プロジェクトのビューで機能しますが、プラグイン・アセンブリからロードされたビューは見つからないため、
私はこのようなルートを設定している: -
RouteTable.Routes.MapRoute(
string.Format("Plugin{0}Route", pluginName),
string.Format(@"Plugin/{0}/{{controller}}/{{action}}", pluginName),
new { },
new string[] { string.Format("{0}.Controllers", pluginName) });
ViewEngineは次のようになります -
public class PluginRazorViewEngine : RazorViewEngine
{
public PluginRazorViewEngine() : base()
{
ViewLocationFormats = new[]
{
"~/Plugin/%1/Views/{1}/{0}.cshtml",
"~/Plugin/%1/Views/{1}/{0}.vbhtml",
"~/Plugin/%1/Views/Shared/{0}.cshtml",
"~/Plugin/%1/Views/Shared/{0}.vbhtml",
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
(%1は、アセンブリの名前に置き換えられます)
であり、アセンブリは次のようにBoCライブラリに登録されています: -
BoC.Web.Mvc.PrecompiledViews.ApplicationPartRegistry.Register(assembly, string.Format("/Plugin/{0}/", pluginName));
プラグインアセンブリ(この例では「accounts」)からビューをロードすると、ビューが見つかってOKと表示されます。
~/plugin/accounts/views/invoice/_viewstart.cshtml
~/plugin/accounts/views/invoice/_viewstart.vbhtml
~/plugin/accounts/views/_viewstart.cshtml
~/plugin/accounts/views/_viewstart.vbhtml
~/plugin/accounts/_viewstart.cshtml
~/plugin/accounts/_viewstart.vbhtml
~/plugin/_viewstart.cshtml
~/plugin/_viewstart.vbhtml
~/_viewstart.cshtml
~/_viewstart.vbhtml
しかし、それは〜/ビュー/ファイル共有生活/ _ViewStart.cshtmlに見ていない - :しかし、それは_ViewStartのためのこれらの場所を検索します。
私はViewEngine(AreaMasterLocationFormats、AreaPartialViewLocationFormats、AreaViewLocationFormats、MasterLocationFormats、PartialViewLocationFormats、およびViewLocationFormats)内のすべての場所の書式を変更しようとしましたが、違いはありません。
私は見てきましたが、System.Web.WebPages.StartPage.GetStartPageはビュー内の開始ページを見つけて返すようですが、見た目を制御する方法についての情報は見つかりません。
私はしかし、私はすぐに取得_ViewStart.cshtmlへ〜/ _ViewStart.cshtml(それが見える場所の一つ)を移動しようとしました: -
Unable to cast object of type 'ASP._Page__ViewStart_cshtml' to type 'System.Web.WebPages.StartPage'.
私が読んだによると、どちらが/ Viewの下に_ViewStartを置く必要があるため、
MVCが_ViewStartを探す場所を変更できますか?
のBOCライブラリが、それは自分のIViewのだ実装していないし、次の呼び出します -
startPage = this.StartPageLookup(page, VirtualPathFactoryManagerViewEngine.ViewStartFileName, this.ViewStartFileExtensions);
しかし、この場合にはViewStartFileNameはちょうど「_ViewStart」であるとViewStartFileExtensionsがちょうどCSHTMLとvbhtmlですが...制御します何もMVCはファイルを検索する必要があります。それは無いように思えるMVCは_ViewStartを検索する場所、あなたが変更することはできませんので
RazorViewから継承した独自の「PluginRazorView」を提案して作成しました。 RenderViewをオーバーライドする必要がありましたが、MVC GetStartPageメソッドが何を複製して、追加のパスを検索するための独自のロジックを追加しようとしましたが、内部と反射の地雷ですので、それが動作することを証明し、私は後でそれを掃除する必要があります。 ここではデリゲートを使用しているのは面白いです...さまざまな検索方法を使用できるようですが、指定する方法はありません。 多くのご協力ありがとうございます。 – Aleks
ええ、それは私があまりにも思ったことです。あなたが言うように、彼らは参照メソッドを変更することを許可するために代理人を使用していますが、次にそれを 'internal'宣言するので、それは実際にそれを変更できるMvc名前空間だけです... – JimmiTh