好的,我正在浏览 ILSpy 并试图弄清楚这里发生了什么,但我运气不佳。
在使用 Razor 引擎的ASP.NET MVC4 应用程序(当然,这肯定适用于 MVC3,可能是 2OutputStack
)中的给定视图中,继承自的属性WebPageBase
只是一个TextWriter
对象堆栈。
通过从这个堆栈中推送和弹出,可以操纵给定 Razor 视图的输出。我希望通过 HTML 辅助扩展方法来利用它,但是我也注意到ViewContext
,它也是HtmlHelper
拥有自己的 TextWriter的公共成员。
现在,我进行了快速检查:(从视图中)
@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
不会丢弃传递给设置器的值,因此在第二个示例的情况下它不仅仅是删除它。 - 沿着调用堆栈移动,
OutputStack
实际上来自PageContext
. ViewContext.Writer
是在WebViewPage.ExecutePageHierarchy()
使用WebViewPage
属性中设置的Output
,也就是最上面的OutputStack
!(只是我,还是这开始看起来像老鼠的依赖巢?)