ASPを解読する.NET 5&MVC 6シリーズチュートリアル(16):カスタムViewファイル検索ロジック
3978 ワード
以前のMVC 5と以前のバージョンでは、Viewファイルのパスを制御するには、
RazorViewEngineによるViewパスの制御
新版
次に、MVcOptionsのインスタンス属性ViewEnginesを変更することで、ビューエンジンの置換を完了します.コードは次のとおりです.
これにより、ビューファイルを検索する際に、新しく登録された
IViewLocationExpanderによるViewパスの制御
MVC 6では、マイクロソフトが別の新しい方法でViewファイルのパスを制御することを提供しています.それは
上記カスタム
最後に、
IViewEngine
インターフェースのFindPartialView
またはFindView
メソッドを書き換える必要があり、すべてのビューエンジンがこのIViewEngine
インターフェース、例えばデフォルトRazorViewEngine
に継承されている.しかし、新バージョンMVC 6では、ビューファイルへのパス方式が異なり、現在はRazorViewEngine
と、新特性IViewLocationExpander
インタフェースの2つの方式がある.RazorViewEngineによるViewパスの制御
新版
RazorViewEngine
では、2つのダミー属性(AreaViewLocationFormats
およびViewLocationFormats
)が用意されており、書き換え制御に使用できます.FindPartialView
またはFindView
メソッドを書き換える必要はありません.例は以下のとおりです.
public class ThemeViewEngine : RazorViewEngine
{
public ThemeViewEngine(IRazorPageFactory pageFactory,
IRazorViewFactory viewFactory,
IViewLocationExpanderProvider viewLocationExpanderProvider,
IViewLocationCache viewLocationCache)
: base(pageFactory,
viewFactory,
viewLocationExpanderProvider,
viewLocationCache)
{
}
public override IEnumerable AreaViewLocationFormats
{
get
{
var value = new Random().Next(0, 1);
var theme = value == 0 ? "Theme1" : "Theme2"; // ,
return base.AreaViewLocationFormats.Select(f => f.Replace("/Views/", "/Views/" + theme + "/"));
}
}
public override IEnumerable ViewLocationFormats
{
get
{
var value = new Random().Next(0, 1);
var theme = value == 0 ? "Theme1" : "Theme2"; // ,
return base.ViewLocationFormats.Select(f => f.Replace("/Views/", "/Views/" + theme + "/"));
}
}
}
次に、MVcOptionsのインスタンス属性ViewEnginesを変更することで、ビューエンジンの置換を完了します.コードは次のとおりです.
services.AddMvc().Configure(options =>
{
options.ViewEngines.Clear();
options.ViewEngines.Add(typeof(ThemeViewEngine));
});
これにより、ビューファイルを検索する際に、新しく登録された
ThemeViewEngine
の論理に従って実行される.IViewLocationExpanderによるViewパスの制御
MVC 6では、マイクロソフトが別の新しい方法でViewファイルのパスを制御することを提供しています.それは
IViewLocationExpander
インタフェースで、このインタフェースを実現することでカスタムロジックを実現し、関連するコンテキストオブジェクトを使用することもできます.例は次のとおりです.
public class ThemeViewLocationExpander : IViewLocationExpander
{
public void PopulateValues(ViewLocationExpanderContext context)
{
var value = new Random().Next(0, 1);
var theme = value == 0 ? "Theme1" : "Theme2";
context.Values["theme"] = theme;
}
public virtual IEnumerable ExpandViewLocations(ViewLocationExpanderContext context,
IEnumerable viewLocations)
{
return viewLocations.Select(f => f.Replace("/Views/", "/Views/" + context.Values["theme"] + "/"));
}
}
上記カスタム
IViewLocationExpander
では、2つの方法がそれぞれPopulateValues
およびExpandViewLocations
・PopulateValues
・ViewLocationExpanderContext
コンテキストに応答のキー値ペアを追加して以降に使用することができ、このコンテキストイメージを利用してActionContext
およびHttpContext
オブジェクトを検索し、これらのオブジェクトを利用して応答の判断操作を行うことができる.ExpandViewLocations
メソッドは、ビューキャッシュがない場合や、ビューキャッシュに対応するkeyのビューファイルが見つからない場合にのみ呼び出され、そのメソッド内でビューの位置を動的に戻すことができます.最後に、
Startup.cs
において、RazorViewEngineOptions
インスタンスオブジェクトのViewLocationExpanders
属性を修正することにより、登録目的を達成し、コードは以下の通りである.
services.Configure(options =>
{
options.ViewLocationExpanders.Add(typeof(ThemViewLocationExpander));
});