私はカスタム(派生)RazorViewEngineを使用し、RazorGeneratorを使用してプリコンパイルしたビューを使用しようとしています。カスタムRazorViewEngineとRazorGeneratorプリコンパイル済みビューの使用
いくつかのコンテキスト:
我々は、複数のクライアントの実装に使用する基本製品を持っています。これにより、基本ビューのコアセットが得られます。ほとんどの場合、ほとんどのビューが機能します。現在、新しいソリューションごとに既存のビューをコピーし、必要に応じて変更します。これは、ビューの95%がクライアント間で同じで、5%が変更されることになります。
基本的なビューのセットをDLLにコンパイルし、クライアント間で再利用したいものです。これまではRazorGeneratorを使ってうまく動作しています。
次に、ビューのカスタマイズ(オーバーライド)を許可します。しかし、注意点があります。私たちのアプリケーションには、ユーザーがいる2つの「モード」があります。モードが異なると、異なるビューが必要になることがあります。
私はRazorGeneratorViewから派生クラスを作成しました。このビューは、基本的にAutofacが解決するUserProfileオブジェクトから "OrderingMode"を検査します。モードに基づいて、ビュー解決のためにパスロケータが置き換えられます。
個々のクライアントアプリケーションというアイデアは、伝統的なビューフォルダで最初にビューの解決を試みます。 Views/{OrderingMode}/{Controller}/{View} .cshtmlのサブディレクトリにのみ追加しています。
ビューが見つからない場合は、コンパイルされたライブラリ(コアビュー)が表示されます。
これにより、クライアントのために必要に応じて個々のビュー/パーシャルをオーバーライドすることができます。
public PosViewEngine() : base()
{
//{0} = View Name
//{1} = ControllerName
//{2} = Area Name
AreaViewLocationFormats = new[]
{
//First look in the hosting application area folder/Views/ordering type
//Areas/{AreaName}/{OrderType}/{ControllerName}/{ViewName}.cshtml
"Areas/{2}/Views/%1/{1}/{0}.cshtml",
//Next look in the hosting application area folder/Views/ordering type/Shared
//Areas/{AreaName}/{OrderType}/{ControllerName}/{ViewName}.cshtml
"Areas/{2}/Views/%1/Shared/(0}.cshtml",
//Finally look in the IMS.POS.Web.Views.Core assembly
"Areas/{2}/Views/{1}/{0}.cshtml"
};
//Same format logic
AreaMasterLocationFormats = AreaViewLocationFormats;
AreaPartialViewLocationFormats = new[]
{
//First look in the hosting application area folder/Views/ordering type
//Areas/{AreaName}/{OrderType}/{ControllerName}/Partials/{PartialViewName}.cshtml
"Areas/{2}/Views/%1/{1}/Paritals/{0}.cshtml",
//Next look in the hosting application area folder/Views/ordering type/Shared
//Areas/{AreaName}/{OrderType}/{ControllerName}/{ViewName}.cshtml
"Areas/{2}/Views/%1/Shared/(0}.cshtml",
//Finally look in the IMS.POS.Web.Views.Core
"Areas/{2}/Views/{1}/{0}.cshtml"
};
ViewLocationFormats = new[]
{
"Views/%1/{1}/{0}.cshtml",
"Views/%1/Shared/{0}.cshtml",
"Views/{1}/{0}.cshtml",
"Views/Shared/{0}.cshtml"
};
MasterLocationFormats = ViewLocationFormats;
PartialViewLocationFormats = new[]
{
"Views/%1/{1}/Partials/{0}.cshtml",
"Views/%1/Shared/{0}.cshtml",
"Views/{1}/Partials/{0}.cshtml",
"Views/Shared/{0}.cshtml"
};
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return base.CreatePartialView(controllerContext, partialPath.ReplaceOrderType(CurrentOrderingMode()));
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
OrderType orderType = CurrentOrderingMode();
return base.CreateView(controllerContext, viewPath.ReplaceOrderType(orderType), masterPath.ReplaceOrderType(orderType));
}
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
return base.FileExists(controllerContext, virtualPath.Replace("%1/",string.Empty));
}
private OrderType CurrentOrderingMode()
{
OrderType result;
_profileService = DependencyResolver.Current.GetService<IUserProfileService>();
if (_profileService == null || _profileService.OrderingType == 0)
{
IApplicationSettingService settingService =
DependencyResolver.Current.GetService<IApplicationSettingService>();
result =
settingService.GetApplicationSetting(ApplicationSettings.DefaultOrderingMode)
.ToEnumTypeOf<OrderType>();
}
else
{
result = _profileService.OrderingType;
}
return result;
}
}
ここには、ViewEngineを登録するためにRazorGeneratorが使用するStartUpクラスがあります。
- このコードは(私はPosViewEngineを登録した後に)最後に実行され、これはサービス提供時に第一に解決さエンジンであることを意味(第1の位置にエンジンを挿入します。
public static class RazorGeneratorMvcStart { public static void Start() { var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) { UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal }; ViewEngines.Engines.Insert(0, engine); // StartPage lookups are done by WebPages. VirtualPathFactoryManager.RegisterVirtualPathFactory(engine); } }
問題がありますアップ応答)。これでビューが見つかり、コアビューです。
私は私のカスタムビューエンジンまず最初にしてRazorGeneratorエンジン
私はFILEEXISTS上の例外で終わるpublic static void Start() { var engine = new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly) { UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal }; ViewEngines.Engines.Clear(); ViewEngines.Engines.Insert(0, new PosViewEngine()); ViewEngines.Engines.Insert(1, engine); // StartPage lookups are done by WebPages. VirtualPathFactoryManager.RegisterVirtualPathFactory(engine); }
(ControllerContext controllerContext、文字列virtualPathを登録するスタートアップのコードを変更した場合)メソッド - "相対仮想パス 'Views/Account/LogOn.cshtml'はここでは許可されていません。
明らかに、物理パスと仮想パスが混在していることとは関係があります。
他の誰かが同じことをしようとしていたようです。hereしかし、私はこれについての答えを見ませんでした。
exitingビューにカスタムコンテンツを追加できますか?私はこれを投稿しましたhttp://stackoverflow.com/questions/38303160/how-to-use-razor-to-process-dynamic-templates-included-in-web-page – Andrus
この方法ではありません。これは、コントローラのアクションに基本的なビューのセットを提供し、必要に応じてオーバーライドするようなコンベンションです。あなたの質問には、カスタムベースビューを使用して独自のプロパティとRazorEngineのようなものを公開し、プロパティを通じてコンテンツを注入することがあります。 – JDBennett