わかりました、ILSpy でクルージングして、ここで何が起こっているのかを整理しようとしていますが、あまり運がありません。
Razor エンジンを使用するASP.NET MVC4 アプリケーション (ただし、これは MVC3、おそらく 2 に適用可能OutputStack
) の特定のビューでは、継承元のプロパティWebPageBase
は単なるTextWriter
オブジェクトのスタックです。
このスタックからプッシュおよびポップすることで、特定の Razor ビューの出力を操作できます。これを HTML ヘルパー拡張メソッドで活用したいと考えていましViewContext
たが、 の public メンバーでもある には独自の TextWriter があることにHtmlHelper
気付きました。
ここで、簡単なチェックを実行しました:(ビュー内から)
@object.ReferenceEquals(this.ViewContext.Writer, this.OutputStack.Peek()) // True
ただし、次のことは私を完全に混乱させます。
@{
// push one on
OutputStack.Push(new StringWriter());
}
Hello!
@{
// capture everything and pop it
string buffer1 = OutputStack.Peek().ToString();
OutputStack.Pop();
}
<pre>@(buffer1)</pre>
@{
// apparently it references the top of the OutputStack
// so this should be essentially the same
var oldWriter = ViewContext.Writer;
ViewContext.Writer = new StringWriter();
}
World!
@{
// revert it and hope for the best
string buffer2 = ViewContext.Writer.ToString();
ViewContext.Writer = oldWriter;
}
<pre>@(buffer2)</pre>
上記の結果は次のとおりです。
Hello!
にキャプチャされbuffer1
、実際には as の後にダンプされ<pre>Hello!</pre>
ます。これは期待されていることであり、望ましいことでもあります。World!
一方、すぐに出力され、その後に空の<pre></pre>
ブロックが続きます。つまり、何もキャプチャしていません。
私の質問は次のとおりです。これらのTextWriter
オブジェクトはどのように相互に関連してViewContext
いるの OutputStack
でしょうか。(むしろ、どのように参照を管理できViewContext
ますか?)
私がそれに出くわしたときの補遺の詳細と他のがらくた。
- の
Writer
プロパティはViewContext
、setter に渡された値を破棄しないため、2 番目の例の場合、値をドロップするだけではありません。 - コール スタックに沿って移動すると、
OutputStack
実際には から来ていPageContext
ます。 ViewContext.Writer
!の先頭にあるプロパティをWebViewPage.ExecutePageHierarchy()
使用して設定されます。(それは私だけですか、それとも依存関係のネズミの巣のように見え始めているのでしょうか? )WebViewPage
Output
OutputStack