How to log request inputstream with HttpModule, then reset InputStream position

时间秒杀一切 提交于 2019-11-28 08:55:59

I've worked out the problem: I think that calling dispose on the StreamReader must be killing the InputStream too.

Instead of using the StreamReader I did the following:

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

So the complete code:

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)
    }
}

Yes the StreamReader will close the supplied stream.

If you're on >v4.5, use a StreamReader constructor that leaves the stream open.

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

I had to make a small tweak to the answer provided by "cbp". When using his code I just got zeros. I moved setting the position to 0 above the read and now it works.

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

You need to use a request filter. Write a class deriving from Stream and register it as a filter.

this answer did not work. it returns an array that contains null values.

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

because the input stream consumed.
Nguyễn Văn Quang

sometime, RequestFilter don't run to method Read. It seem be W3WP don't read content of httprequest by normal way.

If you deploy WEbservice to server. Then use IHttpModule for catch it. Add RequestFilter.

But method Read() of RequestFilter don't run :P

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!