2011年5月6日金曜日

@RenderPageとHtml.RenderPartial

いや~、連休ももうすぐ終わってしまうと思うと、ちょっぴりアンニュイな気持ちになってしまいます。アンニュイってララバイくらい意味がよくわからない。

Razor使ってますか?使ってますよね。お腹すいたらRazorだし、テレビ見ながらRazorですよ!

疲れてるのかな...。

~/Views/Shared/_Partial.cshtml

@{
    var message = Model ?? (PageData.Any() ? PageData.First().Value : null);
}
ゴールデン @message

↑こんな部分ビューを用意しました。

~/Views/Home/Index.cshtml

@{Layout = null;}
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8" />
    <title>連休</title>
</head>
<body>
<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.Partial - 
  @Html.Partial("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
</body>
</html>

↑そしてそれを利用するビューも用意しました。

ここで問題です!このページ(Index.cshtml)を表示するとどういう表示になるでしょーか?

答え

partial1

ビックリした?ねーねー、ビックリした?オレ、すげービックリした。

なんでHtml.RenderPartialだと”ゴールデン ウィーク”と表示されないんでしょうね。ソース追っかけたりしてスゴイ悩んだんですよ。そもそもRazorではストリームに直接出力うするHtml.RenderPartial使えないのか!?とか仕様を疑ったり(RenderPartialの実装がMVC3になってTextWriter渡す実装に変わってるから関係ないのにね)。

うーん、煮詰まった。ふと、順番入れ替えたらどうなるのか試してみたんす。

<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.Partial - 
  @Html.Partial("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>

@RenderPageを最後に移動。

partial2

おや~?ちゃんと出た。あれ~。この際Html.Partialは無視して試しに親戚のHtml.RenderActionはどうなるのか試してみたっす。

HomeControllerに以下を追加。

[ChildActionOnly]
public ActionResult Week()
{
    return Content("ウィーク");
}

Index.cshtmlを以下のように変更(@RenderPageを最初に持って来てHtml.RenderAction追加)。

<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.RenderAction - 
  ゴールデン @{Html.RenderAction("Week");}</p>

partial3

Html.RenderActionは平気みたい。このまま@RenderPageを最後に移動。

<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.RenderAction - 
  ゴールデン @{Html.RenderAction("Week");}</p>
<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>

 

partial4

ちゃんと出ますね。ということはですよ、同じWebPage中では@RenderPageした後はHtml.RenderPartialが正しく動かないということですよ。これってもしかして...。あ、いや、仕様かもしれないし。どういう事?教えてWebMatrixMan~!

※@RenderPage自体がRazor構文なのでWeb Formsでは関係ない問題です。

dotnetConf2015 Japan

https://github.com/takepara/MvcVpl ↑こちらにいろいろ置いときました。 参加してくださった方々の温かい対応に感謝感謝です。