好的,我正在与ILSpy进行交流,并试图弄清这里发生了什么,但是我运气不高。
在使用Razor引擎的ASP.NET MVC4应用程序中的给定视图中(尽管可以肯定,这适用于MVC3,可能是2),从OutputStack
继承的WebPageBase
属性只是TextWriter
对象的堆栈。
通过推入和弹出该堆栈,可以操纵给定Razor视图的输出。我希望通过HTML helper扩展方法来利用它,但是我也注意到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
中,并实际上作为<pre>Hello!</pre>
转储。这是预期和期望的。另一方面,
World!
立即输出,随后是空的<pre></pre>
块;换句话说,它没有捕获任何东西。我的问题如下:这些
TextWriter
对象如何相互关联,为什么我不能像在ViewContext
顶部一样通过OutputStack
管理引用? (相反,如何通过ViewContext
管理引用?)附录
我碰到的细节和其他废话。
Writer
的ViewContext
属性不会丢弃传递给setter的值,因此在第二个示例中,它不只是将其删除。沿着调用堆栈移动,
OutputStack
实际上来自PageContext
。使用
ViewContext.Writer
属性WebViewPage.ExecutePageHierarchy()
在WebViewPage
中设置Output
,这是OutputStack
的顶部! (仅仅是我一个人,还是开始看起来像老鼠的依赖巢?) 最佳答案
我将发表评论作为答案。它可能说明解决了您问题的学术部分,但肯定可以解决了问题的实际部分,最重要的是,您尝试解决的是最初的问题。
在您的助手中,您可以获取当前视图的OutputStack
:
public static void MyHelper(this HtmlHelper html)
{
var stack = ((WebPageBase)html.ViewDataContainer).OutputStack;
... you could push and pop here and solve your real world problem
}
关于asp.net - TextWriter引用行为异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17557732/