WebMatrix 2 / Razor:switch と RenderPage()

執筆日時:

f:id:daruyanagi:20130106043226p:plain

たとえば、

というのをやってみたいとき。

を作成して、

という処理を書けばいいよね(WebMatrix のルーティング - だるろぐ)。

こういう処理は if で分岐してもいいのだけど、将来的に UrlData.Count() >= 2 の処理を書くことも考えて switch にするのが個人的には好み。いかにも「処理を切り替えています!」みたいな感じで。

でも、そういえば Razor で switch って書いたことないな。どうやって書くんだろう。

@{
var db = Database.Open("db");
var query = "SELECT * FROM Post ORDER BY CreatedAt DESC";
var posts = db.Query(query);
}

@switch (UrlData.Count) { case 0: foreach (var post in posts) { @RenderPage("_Single.cshtml", post) } break; default: @RenderPage("_Single.cshtml", posts.First()) break; }

……と思ったけど普通に書いて動いた。

f:id:daruyanagi:20130106050950p:plain

リストの時は _Single.cshtml のレンダリングを foreach で回して、個別ページの時は一度だけ出力する。_Single.cshtml は何度も使う単一 Post の表示を切り出したもので、部分ビューと呼んだりもするのだけど、内容はこんな適当な感じ。

@{
var post = PageData.First().Value;
}

<div>
<header>
<h1>@post.Title</h1>
<p>@post.CreatedAt</p>
</header>
<article>
@post.Body
</article>
<footer>
<ul>
<li><a href="@post.Id">Show</a></li>
<li><a href="Edit/@post.Id">Edit</a></li>
<li><a href="Delete/@post.Id">Delete</a></li>
</ul>
</footer>
</div>

RenderPage() を使ったデータの受け渡しがいまいちよくわからなかったのだけど、PostData を介しているみたいで、PageData.First() と書いたらなんとなく動いた。

とはいえ、PageData / Page はいろんなところで便利に使っちゃったりする。上書きなどの汚染がちょっと怖いかもしれない。念のため Visual Studio でなかをのぞいてみた。

f:id:daruyanagi:20130106050116p:plain

RenderPage(…, post, 1, 2) と渡してみたのだけど、params の key は順に 0、1、2 とふられるみたい。なので、Page.Title = "hoge"; といった感じで使う分には問題がなさそう。PageData[0] で post がとれるはず。まぁ、わざわざ上書きしたらこの限りではないと思うけれど。

注意

@switch (UrlData.Count)
{
case 0:
foreach (var post in posts)
{
RenderPage("_Single.cshtml", post);
}
break;
default:
RenderPage("_Single.cshtml", posts.First());
break;
}

一応これでもコンパイルは通るのだけど、RenderPage() は動かない。@RenderPage() って書かなきゃいけないんだね*1。ここら辺はまだわかるようでよくわかっていないところ。

*1:文末の ; は不要になる