2008-12-22 9 views
17

Wie zeichne ich den HTML-Code (in meiner Instanz für die Protokollierung) am besten auf einer aspx-Seite auf?Erfassen von HTML, das von ASP.NET generiert wurde

Ich möchte nicht mit Response.Write auf die Seite zurückschreiben, da es mein Website-Layout vermasselt.

Mit dem Response.OutputStream oder Response.Output Stream führt zu einer Argument ({System.ArgumentException:. Strom war nicht lesbar)

+0

Um es kurz zu machen, überschreiben Sie die Render-Methode für die Seite. Ähnliche Fragen und Antworten [hier] (http://stackoverflow.com/questions/56279/export-aspx-to-html) –

Antwort

23

Gute Frage, ich musste ausprobieren und sehen, ob ich ein HttpModule erstellen könnte, um zu tun, was Sie beschreiben.

Ich hatte kein Glück zu versuchen, aus dem Responsestream zu lesen, aber die Verwendung des ResponseFilter gab mir eine Möglichkeit, den Inhalt zu erfassen.

Der folgende Code scheint ziemlich gut zu funktionieren, und ich dachte, vielleicht könnten Sie den Code als Basis verwenden. Aber denken Sie daran, dass dies nur etwas ist, was ich schnell zusammengestellt habe, es wurde in keiner Weise getestet. Verwenden Sie es daher nicht in einer Produktionsumgebung ohne entsprechende Überprüfung/Tests und dergleichen. Fühlen Sie sich frei, es zu kommentieren;)

public class ResponseLoggerModule : IHttpModule 
{ 
    private class ResponseCaptureStream : Stream 
    { 
     private readonly Stream _streamToCapture; 
     private readonly Encoding _responseEncoding; 

     private string _streamContent; 
     public string StreamContent 
     { 
      get { return _streamContent; } 
      private set 
      { 
       _streamContent = value; 
      } 
     } 

     public ResponseCaptureStream(Stream streamToCapture, Encoding responseEncoding) 
     { 
      _responseEncoding = responseEncoding; 
      _streamToCapture = streamToCapture; 

     } 

     public override bool CanRead 
     { 
      get { return _streamToCapture.CanRead; } 
     } 

     public override bool CanSeek 
     { 
      get { return _streamToCapture.CanSeek; } 
     } 

     public override bool CanWrite 
     { 
      get { return _streamToCapture.CanWrite; } 
     } 

     public override void Flush() 
     { 
      _streamToCapture.Flush(); 
     } 

     public override long Length 
     { 
      get { return _streamToCapture.Length; } 
     } 

     public override long Position 
     { 
      get 
      { 
       return _streamToCapture.Position; 
      } 
      set 
      { 
       _streamToCapture.Position = value; 
      } 
     } 

     public override int Read(byte[] buffer, int offset, int count) 
     { 
      return _streamToCapture.Read(buffer, offset, count); 
     } 

     public override long Seek(long offset, SeekOrigin origin) 
     { 
      return _streamToCapture.Seek(offset, origin); 
     } 

     public override void SetLength(long value) 
     { 
      _streamToCapture.SetLength(value); 
     } 

     public override void Write(byte[] buffer, int offset, int count) 
     { 
      _streamContent += _responseEncoding.GetString(buffer); 
      _streamToCapture.Write(buffer, offset, count); 
     } 

     public override void Close() 
     { 
      _streamToCapture.Close(); 
      base.Close(); 
     } 
    } 

    #region IHttpModule Members 

    private HttpApplication _context; 
    public void Dispose() 
    { 

    } 

    public void Init(HttpApplication context) 
    { 
     _context = context; 

     context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); 
     context.PreSendRequestContent += new EventHandler(context_PreSendRequestContent); 
    } 

    void context_PreRequestHandlerExecute(object sender, EventArgs e) 
    { 
     _context.Response.Filter = new ResponseCaptureStream(_context.Response.Filter, _context.Response.ContentEncoding); 
    } 

    void context_PreSendRequestContent(object sender, EventArgs e) 
    { 
     ResponseCaptureStream filter = _context.Response.Filter as ResponseCaptureStream; 

     if (filter != null) 
     { 
      string responseText = filter.StreamContent; 

      // Logging logic here 
     } 
    } 

    #endregion 
} 
+0

Das ist genau das, was ich für http://StackOverflow.com/Questions/1020045/how-to-trace-scriptservice-webservice-requests benötigt. Vielen Dank! – jrummell

+0

Ich musste das BeginRequest-Ereignis verwenden, um den Filter einzurichten, PreRequestHandlerExecute wurde nicht in meinem HttpModule ausgelöst. Ich habe nicht nach dem Grund gesucht, aber vielleicht hilft das jemand anderem. – JeremyWeir

+0

Erstaunliche Lösung des Problems! –

4

Viele Last-Tester können Sie die HTTP-Antworten generiert, protokollieren, aber tragen in Bei ASP.NET könnten das einige sehr große Protokolldateien sein.

Edit: Response.Filter nach Tom Jelen Code ist so konzipiert, dass diese Art von Aufsicht geben und Response.Outputstream ist sonst nicht lesbar.

Edit 2: Für eine Seite eher als ein Httpmodule

public class ObserverStream : Stream 
{ 
    private byte[] buffer = null; 
    private Stream observed = null; 

    public ObserverStream (Stream s) 
    { 
    this.observed = s; 
    } 

    /* important method to extend #1 : capturing the data */ 
    public override void Write(byte[] buffer, int offset, int count) 
    { 
    this.observed.Write(buffer, offset, count); 
    this.buffer = buffer; //captured! 
    } 

    /* important method to extend #2 : doing something with the data */ 
    public override void Close() 
    { 
    //this.buffer available for logging here! 
    this.observed.Close(); 
    } 

    /* override all the other Stream methods/props with this.observed.method() */ 

    //... 

} 

und in Ihrem Page_Load (oder vor Ihrer Antwort sowieso geschrieben wird)

Response.Filter = new ObserverStream(Response.Filter); 
+0

Die Verwendung des Response.OutputStream- oder Response.Output-Streams führt zu einer ArgumentException ({System.ArgumentException: Stream war nicht lesbar.) – lastas

+0

Hast du zuerst versucht, die Null zu setzen? In einen lesbaren MemStream schreiben? (Ich feuere mich jetzt selbst an, weil ich wissen will, wie ich das mache) – annakata

+0

Heh, ich wollte gerade den ganzen Response.Filter-Code posten, den ich gerade geschrieben hatte, und fand, dass Tom Jelen genau das schon gemacht hat. Arbeitete für mich auch grundsätzlich :) – annakata

1

Eine Möglichkeit, serverseitige XMLHTTP zu machen Anfrage an Ihren eigenen Server. Ergreifen Sie das Ergebnis und speichern Sie es in einer Datei oder DB.

Alternativ können Sie AJAX auf dem Client verwenden, nehmen Sie das Ergebnis und POST es zurück auf den Server.

+2

Verdoppelung auf Anfragen scheint schlecht angesichts der Daten gibt es irgendwo das erste Mal um – annakata

Verwandte Themen