ロードマップにあったビューにサフィックスを付けるあれです。
機能自体は非常にシンプルで DisplayModes クラスを使うだけですが、名前空間が System.Web.WebPages となっているので注意してください。WebPages にあるということは WebMatrix でも使えるのかもしれないですが未確認です。
とりあえず使う
例としてチャックさんの @IT 記事で紹介されている、携帯キャリア毎にビューを分ける機能を実装してみます。
ASP.NET MVCのビュー・エンジンと、柔軟なHTMLマークアップ − @IT
基本的に DisplayModes の定義は Global.asax.cs の Application_Start に書きます。今まではビューエンジンを拡張する必要がありましたが、MVC 4 では以下のような定義を書くだけです。
DisplayModes.Modes.Insert(0, new DefaultDisplayMode("DoCoMo") { ContextCondition = context => context.Request.UserAgent.IndexOf("DoCoMo/") != -1 }); DisplayModes.Modes.Insert(1, new DefaultDisplayMode("iPhone") { ContextCondition = context => context.Request.UserAgent.IndexOf("iPhone/") != -1 }); … 省略 …
Modes がコレクションになっているので、Insert で DefaultDisplayMode のインスタンスを追加していきます。Insert を使う理由は Modes の先頭から評価されるので、順番によっては別の定義が使われてしまうかもしれないからですね。
今回は UserAgent を見て判別していますが、UserHostAddress を使えば携帯ゲートウェイのアドレスを使って振り分けることもできます。HttpContext を受け取って bool を返すラムダ・デリゲートであれば何でも指定できます。
定義は完成したのでビューを用意します。今回はサンプルなので _Layout.cshtml だけ用意しました。
ディレクトリで分離したい気持ちが出てきますね…。今のところはサフィックスしか定義できないので、フィードバック投げておけばいいかもしれないです。
注目してもらいたいのがビューの検索順です。以下のような順番でビューの検索が行われるようになっています。
- Display Mode で定義されたサフィックスを持つビュー (例: _Layout.DoCoMo.cshtml)
- サフィックスを持たないビュー (例: _Layout.cshtml)
C++ の template 風に言うと特殊化です(謎。つまり、必要な部分だけ専用のビューを用意することが出来るので、全体としての開発コストを下げることが出来そうですね。