2009-11-05 9 views
23

Sto cercando di registrare il contenuto di una richiesta HTTP, utilizzando un IHttpModule in questo modo:Come accedere richiesta InputStream con HttpModule, quindi reimpostare la posizione InputStream

public class LoggingModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += ContextBeginRequest; 
    } 

    private void ContextBeginRequest(object sender, EventArgs e) 
    { 
     var request = ((HttpApplication)sender).Request; 
     string content; 

     using (var reader = new StreamReader(request.InputStream)) 
     { 
      content = reader.ReadToEnd(); 
     } 

     LogRequest(content) 
    } 
} 

Il problema è che dopo aver letto il flusso di input per Alla fine, sembra che l'InputStream sia scomparso o più probabilmente, il cursore si trova alla fine del flusso.

Ho provato request.InputStream.Position = 0; e request.InputStream.Seek(0, SeekOrigin.Begin); ma nessuno dei due funziona.

risposta

31

Ho risolto il problema: penso che la chiamata di Dispose su StreamReader debba uccidere anche InputStream.

Invece di usare lo StreamReader ho fatto la seguente:

 var bytes = new byte[request.InputStream.Length]; 
     request.InputStream.Read(bytes, 0, bytes.Length); 
     request.InputStream.Position = 0; 
     string content = Encoding.ASCII.GetString(bytes); 

Quindi il codice completo:

public class LoggingModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += ContextBeginRequest; 
    } 

    private void ContextBeginRequest(object sender, EventArgs e) 
    { 
     var request = ((HttpApplication)sender).Request; 

     var bytes = new byte[request.InputStream.Length]; 
     request.InputStream.Read(bytes, 0, bytes.Length); 
     request.InputStream.Position = 0; 
     string content = Encoding.ASCII.GetString(bytes); 

     LogRequest(content) 
    } 
} 
+6

Fare attenzione con la codifica lì, penso che vorrete che sia Encoding.UTF8.GetString (byte); – SimonF

+0

Ottima risposta !! +1 –

1

È necessario utilizzare un request filter. Scrivi una classe derivata da Stream e registrala come filtro.

1

questa risposta non ha funzionato. restituisce una matrice che contiene valori nulli.

 
     var bytes = new byte[request.InputStream.Length]; 
     request.InputStream.Read(bytes, 0, bytes.Length); 
     request.InputStream.Position = 0; 
     string content = Encoding.ASCII.GetString(bytes);

perché il flusso di input è stato consumato.

-1

a volte, RequestFilter non eseguire il metodo di lettura. Sembra che W3WP non legga il contenuto di httprequest in modo normale.

Se si distribuisce WEbservice sul server. Quindi utilizzare IHttpModule per prenderlo. Aggiungi RequestFilter.

Ma il metodo Read() di RequestFilter non corrono: P

13

Sì, la StreamReader si chiuderà il flusso in dotazione.

Se si è su> v4.5, utilizzare un costruttore StreamReader che lascia aperto il flusso.

using (var reader = new StreamReader(request.InputStream, Encoding.UTF8, true, 1024, true)) 
{ 
    content = reader.ReadToEnd(); 
} 
1

Ho dovuto apportare un piccolo ritocco alla risposta fornita da "cbp". Usando il suo codice ho appena preso degli zeri. Ho spostato la posizione su 0 sopra la lettura e ora funziona.

var bytes = new byte[Request.InputStream.Length]; 
Request.InputStream.Position = 0; 
Request.InputStream.Read(bytes, 0, bytes.Length); 
string content = Encoding.ASCII.GetString(bytes);