2009-11-05 10 views
23

próbuję zalogować zawartości żądania HTTP, przy użyciu IHttpModule tak:Jak zalogować żądania InputStream z HttpModule, a następnie przywrócić pozycję 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) 
    } 
} 

Problem polega na tym, że po przeczytaniu strumienia wejściowego koniec, wydaje się, że InputStream zniknął lub jest bardziej prawdopodobne, kursor znajduje się na końcu strumienia.

Próbowałem request.InputStream.Position = 0; i request.InputStream.Seek(0, SeekOrigin.Begin);, ale nie działa.

Odpowiedz

31

Rozwinąłem problem: Myślę, że wywoływanie z wykorzystaniem StreamReadera również musi zabić InputStream.

Zamiast StreamReader zrobiłem następujące:

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

Więc kompletny kod:

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

Uważaj na kodowanie, myślę, że będziesz chciał, żeby to było Encoding.UTF8.GetString (bytes); – SimonF

+0

Świetna odpowiedź !! +1 –

1

ta odpowiedź nie działa. zwraca tablicę zawierającą wartości puste.

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

ponieważ strumień wejściowy został zużyty.

-1

kiedyś, RequestFilter nie należy uruchamiać metody Read. Wygląda na to, że W3WP nie odczytuje treści w standardzie httprequest.

Jeśli wdrożysz WEbservice na serwerze. Następnie użyj modułu IHttpModule, aby go złapać. Dodaj RequestFilter.

Ale metoda Read() z RequestFilter nie działają: P

13

Tak, StreamReader zamknie dostarczonego strumienia.

Jeśli korzystasz z wersji> v4.5, użyj konstruktora StreamReader, który pozostawia otwarty strumień.

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

Musiałem wprowadzić drobne poprawki do odpowiedzi dostarczonej przez "cbp". Kiedy używam jego kodu, mam tylko zera. Przesunąłem ustawienie pozycji na 0 powyżej odczytu i teraz działa.

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