我想扩展 WebFormViewEngine 以便我可以执行一些后处理 - 我希望它完成它的工作,然后将 Html 交给我,这样我就可以对其进行最后的润色。它需要作为 View/ViewEngine 完成,因为我需要访问 ViewData。
不幸的是,似乎没有办法从 WebFormView 中取回 Html,也没有办法将自定义 HtmlTextWriter 交给 WebFormView 或 ViewPage。
当然有办法做到这一点?不?
利特尔查瓦
我想扩展 WebFormViewEngine 以便我可以执行一些后处理 - 我希望它完成它的工作,然后将 Html 交给我,这样我就可以对其进行最后的润色。它需要作为 View/ViewEngine 完成,因为我需要访问 ViewData。
不幸的是,似乎没有办法从 WebFormView 中取回 Html,也没有办法将自定义 HtmlTextWriter 交给 WebFormView 或 ViewPage。
当然有办法做到这一点?不?
利特尔查瓦
您可以使用操作过滤器来执行此操作。在 asp.net/mvc 上查看本教程。您想使用 ResultsFilter。
作为替代方案,您可以覆盖 Controller 的虚拟 OnResultExecuted 方法。
您可以通过重写 WebFormView 类的 Render 方法在视图呈现之前捕获输出接收器。诀窍是输出接收器不是 System.IO.TextWriter 编写器,而是 viewContext 的 Writer 属性。此外,您必须扩展 WebFormViewEngine 以返回您的视图。
public class MyViewEngine : WebFormViewEngine
{
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return new MyView(partialPath, null);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
return new MyView(viewPath, masterPath);
}
}
public class MyView : WebFormView
{
public MyView(string inViewPath, string inMasterPath) : base(inViewPath, inMasterPath) { }
public MyView(string inViewPath) : base(inViewPath) { }
public override void Render(ViewContext viewContext, System.IO.TextWriter writer)
{
//make a switch to custom output receiver
var oldWriter = viewContext.Writer;
viewContext.Writer = new System.IO.StringWriter();
base.Render(viewContext, null);
viewContext.Writer.Close();
//get output html
var html = ((System.IO.StringWriter)viewContext.Writer).GetStringBuilder();
//perform processing
html.Replace('a', 'b');
//retransmit output
viewContext.Writer = oldWriter;
viewContext.Writer.Write(html);
}
}
好的,我以前从未这样做过,但我查看了反射器和 MVC 组件。看起来好像您可以使用您的对象扩展 ViewPage 和 ViewPage 和 ViewMasterPage 对象。在您自己的对象中,您可以覆盖渲染方法并获取 HtmlTextWriter 的句柄。然后把它传给基地,让它做这件事。像这样的东西(这是未经测试的,只是理论上的,可能有更多的方法需要覆盖。)我建议使用反射器来看看它现在是如何完成的,甚至是像 Spark 这样的其他视图引擎是如何做到的。
public class MyPage : ViewPage
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//Do custom stuff here
base.Render(writer);
}
}
public class MyPage<TModel> : MyPage where TModel : class
{
}