2008-12-22 13 views
17

Come faccio a catturare al meglio l'HTML (nella mia istanza, per la registrazione) reso da una pagina aspx?Catturare l'HTML generato da ASP.NET

Non desidero dover scrivere di nuovo alla pagina utilizzando Response.Write, poiché compromette il layout del mio sito.

Utilizzando il Response.OutputStream oi risultati del flusso di Response.Output in un ArgumentException ({System.ArgumentException:. Stream non era leggibile)

+0

Per dirla breve, sostituire il metodo Render per la pagina. Domande e risposte simili [qui] (http://stackoverflow.com/questions/56279/export-aspx-to-html) –

risposta

23

Buona domanda, ho dovuto provare e vedere se potevo creare un HttpModule per fare ciò che stai descrivendo.

Non ho avuto alcuna fortuna nel tentativo di leggere dal responsestream, ma l'utilizzo di ResponseFilter mi ha fornito un modo per acquisire il contenuto.

Il seguente codice sembra funzionare piuttosto bene, e ho pensato che forse si potrebbe usare il codice come base. Ma ricorda che questo è solo qualcosa che ho buttato insieme velocemente, non è stato testato in alcun modo. Quindi non usarlo in qualsiasi ambiente di produzione senza una corretta revisione/test e così via. Sentitevi liberi di commentare comunque;)

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

Questo è proprio quello di cui avevo bisogno per http://stackoverflow.com/questions/1020045/how-to-trace-scriptservice-webservice-requests. Grazie! – jrummell

+0

Ho dovuto utilizzare l'evento BeginRequest per configurare il filtro, PreRequestHandlerExecute non è stato attivato nel mio HttpModule. Non ho guardato al perché, ma forse questo aiuterà qualcun altro. – JeremyWeir

+0

Incredibile soluzione del problema! –

4

Molti tester di carico vi permetterà di registrare le risposte HTTP generate, ma tenere a mente con ASP.NET quelli potrebbero essere alcuni file di log molto grandi.

Modifica: Response.Filter come per codice di Tom Jelen è progettato per fornire questo tipo di supervisione e Response.Outputstream è altrimenti illeggibile.

Edit 2: Per una pagina piuttosto che un 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() */ 

    //... 

} 

e nel tuo Page_Load (o prima la risposta è scritto in ogni caso)

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

Utilizzo del flusso Response.OutputStream o Response.Output in ArgumentException ({System.ArgumentException: Stream non era leggibile.) – lastas

+0

Hai cercato di azzerare prima? Scrivi su un MemStream leggibile? (sparando solo contro me stesso ora perché voglio sapere come farlo) – annakata

+0

Heh, stavo per pubblicare tutto il codice Response.Filter che avevo appena scritto e ho scoperto che Tom Jelen ha già fatto esattamente questo. Ha funzionato anche per me in pratica :) – annakata

1

Un modo per rendere XMLHTTP lato server richiesta al tuo server. Prendi il risultato e salvalo in un file o in un DB.

In alternativa è possibile utilizzare AJAX sul client, prelevare il risultato e inviarlo nuovamente al server.

+2

raddoppiare sulle richieste sembra male dato che i dati sono lì da qualche parte la prima volta intorno a – annakata

Problemi correlati