Method for intercepting asp.net output streams and processing them

  • 2021-01-18 06:23:27
  • OfStack

The example in this paper mainly implements some processing of the generated HTML pages before they are output to the client.

Method the principle is: the Response output redirection to the custom of container, also is our StringBuilder object, all the output to the page in HTML became to StringBuilder output, and then we to StringBuilder processing is completed, then the Response output redirected to the original page, and then through Response. Write method StringBuilder content output to the page.

Reflecting is used here because the OutPut property of the Response object is read-only, and by decomcompiling the assembly of the class, it is found that OutPut is actually the internal private member _writer to implement the output. Therefore, the value of this member is overwritten by reflection to redirect the output stream.

Specific functional codes are as follows:


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Text; 
using System.IO; 
using System.Reflection; 
public partial class _Default : System.Web.UI.Page  
{ 
  StringBuilder content = new StringBuilder(); 
  TextWriter tw_old, tw_new; 
  FieldInfo tw_field; 
  protected void Page_Load(object sender, EventArgs e) 
  { 
    var context = HttpContext.Current; 
 
    tw_old = context.Response.Output;//Response The original OutPut 
    tw_new = new StringWriter(content);//1 a StringWriter, Used to retrieve page content  
    var type_rp = context.Response.GetType(); 
    // Gets the object's private fields by reflection  
    tw_field = type_rp.GetField("_writer", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
    tw_field.SetValue(context.Response, tw_new); 
  } 
  protected override void Render(HtmlTextWriter writer) 
  { 
    base.Render(writer); 
    // Replace the back Response the OutPut 
    tw_field.SetValue(HttpContext.Current.Response, tw_old); 
    // Do your own handling  
    content.AppendLine("<!-- River's lake boy -->"); 
    HttpContext.Current.Response.Write(content.ToString()); 
  } 
} 
 

Method 2, using HttpModul:


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.IO; 
using System.Text; 
using System.Reflection; 
/// <summary> 
///HttpModule  Summary of the  
/// </summary> 
public class HttpModule : IHttpModule 
{ 
  private HttpApplication _contextApplication; 
  private TextWriter tw_new, tw_old; 
  private StringBuilder _content; 
  private FieldInfo tw_field; 
  public void Init(HttpApplication context) 
  { 
    _contextApplication = context; 
    _contextApplication.PreRequestHandlerExecute += new EventHandler(_contextApplication_PreRequestHandlerExecute); 
  } 
  public void Dispose() 
  { 
    _contextApplication = null; 
    _contextApplication.Dispose(); 
  } 
  public void _contextApplication_PreRequestHandlerExecute(object sender, EventArgs e) 
  { 
    HttpContext context = _contextApplication.Context; 
 
    var _page = context.Handler as System.Web.UI.Page; 
    _page.Unload += new EventHandler(_page_Unload); 
 
    _content = new StringBuilder(); 
    tw_old = context.Response.Output;//Response The original OutPut 
    tw_new = new StringWriter(_content);//1 a StringWriter, Used to retrieve page content  
    var type_rp = context.Response.GetType(); 
    tw_field = type_rp.GetField("_writer", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
    tw_field.SetValue(context.Response, tw_new); 
  } 
  void _page_Unload(object sender, EventArgs e) 
  { 
    // Replace the back Response the OutPut 
    tw_field.SetValue(HttpContext.Current.Response, tw_old); 
    // Do your own handling  
    _content.AppendLine("<!-- River's lake boy -->"); 
    HttpContext.Current.Response.Write(_content.ToString()); 
  } 
} 
 

Method 3:


public class HttpModule : IHttpModule 
{ 
  private HttpApplication _contextApplication; 
  private TextWriter tw_new, tw_old; 
  private StringBuilder _content; 
  private FieldInfo tw_field; 
  public void Init(HttpApplication application) 
  { 
    _contextApplication = application; 
    _contextApplication.BeginRequest += new EventHandler(_contextApplication_BeginRequest); 
    _contextApplication.EndRequest +=new EventHandler(_contextApplication_EndRequest); 
  } 
  void _contextApplication_BeginRequest(object sender, EventArgs e) 
  { 
    _content = new StringBuilder(); 
    tw_old = _contextApplication.Response.Output; 
    tw_new = new StringWriter(_content); 
    var type_rp = _contextApplication.Response.GetType(); 
    tw_field = type_rp.GetField("_writer", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
    tw_field.SetValue(_contextApplication.Response, tw_new); 
  } 
  void _contextApplication_EndRequest(object sender, EventArgs e) 
  { 
    tw_field.SetValue(_contextApplication.Response, tw_old); 
    // Do your own handling  
    _content.AppendLine("<!--jhxz-->"); 
    _contextApplication.Response.Write(_content.ToString()); 
  } 
  public void Dispose() 
  { 
    _contextApplication = null; 
    _contextApplication.Dispose(); 
  } 
}

I believe that this article described to everyone's asp.net program design has a definite reference value.


Related articles: