3

わかりました、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()使用して設定されます。(それは私だけですか、それとも依存関係のネズミの巣のように見え始めているのでしょうか? )WebViewPageOutputOutputStack
4

2 に答える 2