Как регистрировать запрос входного потока с помощью HttpModule, затем reset Позиция InputStream
Я пытаюсь зарегистрировать содержимое http-запроса, используя IHttpModule, например:
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)
}
}
Проблема заключается в том, что после прочтения входного потока до конца InputStream, похоже, либо исчез, либо, скорее всего, курсор находится в конце потока.
Я пробовал request.InputStream.Position = 0;
и request.InputStream.Seek(0, SeekOrigin.Begin);
, но не работал.
Ответы
Ответ 1
Я решил проблему: я думаю, что вызов dispose на StreamReader также должен убивать InputStream.
Вместо использования StreamReader я сделал следующее:
var bytes = new byte[request.InputStream.Length];
request.InputStream.Read(bytes, 0, bytes.Length);
request.InputStream.Position = 0;
string content = Encoding.ASCII.GetString(bytes);
Итак, полный код:
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)
}
}
Ответ 2
Да StreamReader закроет предоставленный поток.
Если вы находитесь нa > v4.5, используйте конструктор StreamReader, который оставляет поток открытым.
using (var reader = new StreamReader(request.InputStream, Encoding.UTF8, true, 1024, true))
{
content = reader.ReadToEnd();
}
Ответ 3
Вам нужно использовать фильтр запросов. Напишите класс, полученный из Stream и зарегистрируйте его как фильтр.
Ответ 4
этот ответ не сработал. он возвращает массив, содержащий нулевые значения.
var bytes = new byte[request.InputStream.Length];
request.InputStream.Read(bytes, 0, bytes.Length);
request.InputStream.Position = 0;
string content = Encoding.ASCII.GetString(bytes);
потому что потребляемый входной поток.
Ответ 5
Мне пришлось немного подправить ответ, предоставленный "cbp". При использовании его кода я получил нули. Я переместил положение на 0 выше прочитанного и теперь оно работает.
var bytes = new byte[Request.InputStream.Length];
Request.InputStream.Position = 0;
Request.InputStream.Read(bytes, 0, bytes.Length);
string content = Encoding.ASCII.GetString(bytes);
Ответ 6
sometime, RequestFilter
не запускаются в метод Read. Кажется, W3WP не читает содержимое httprequest
обычным способом.
Если вы развертываете WEbservice
на сервер. Затем используйте IHttpModule для его улова. Добавить RequestFilter
.
Но метод Read()
RequestFilter не запускается: P