RazorGenerator を使用して、カスタム (派生) RazorViewEngine とプリコンパイル済みビューを使用しようとしています。
いくつかのコンテキスト:
複数のクライアントの実装に使用する基本製品があります。これで、基本ビューのコア セットができました。ほとんどの場合、ほとんどのビューが機能します。現時点では、新しいソリューションごとに既存のビューをコピーし、必要に応じて変更することになります。これにより、ビューの 95% がクライアント間で同じになり、5% が変更されます。
私がやりたいことは、ビューの基本セットを取得し、それらを DLL にコンパイルして、クライアント間で再利用することです。これまでのところ、RazorGenerator を使用してうまく機能しています。
次のステップは、ビューのカスタマイズ (オーバーライド) を可能にすることです。ただし、注意点があります。このアプリケーションには、ユーザーがいる 2 つの「モード」があります。ユーザーがいるモードでは、別のビューが必要になる場合があります。
RazorGeneratorView から派生クラスを作成しました。このビューは基本的に、Autofac が解決する UserProfile オブジェクトから「OrderingMode」を検査します。モードに基づいて - パス ロケーターはビューの解像度に置き換えられます。
個々のクライアント アプリケーションであるという考え方は、最初に従来の Views フォルダーでビューを解決しようとします。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;
}
}
以下は、RazorGenerator が ViewEngine を登録するために使用する StartUp クラスです。
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);
}
}
問題は:
- このコードは最後に (PosViewEngine を登録した後) 実行され、最初の位置にエンジンが挿入されます (これは、応答を提供するときに最初に解決されるエンジンであることを意味します)。これはビューを見つけることになります - それはコアビューです。
StartUp のコードを変更して、最初にカスタム ビュー エンジンを登録し、次に RazorGenerator エンジンを登録するとします。
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); }
FileExists(ControllerContext controllerContext, string virtualPath) メソッドで例外が発生します-「相対仮想パス 'Views/Account/LogOn.cshtml' はここでは許可されていません。」
明らかに、物理パスと仮想パスの両方が混在していることに関係があります。
他の誰かがここで同じことをしようとしていたようですが、これに関する答えはありませんでした。