如何使用HttpModule记录请求输入流,然后重置InputStream位置

时间:2009-11-05 07:12:08

标签: .net httpmodule inputstream

我正在尝试使用像这样的IHttpModule记录http请求的内容:

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);,但都没有效果。

6 个答案:

答案 0 :(得分:36)

我解决了这个问题:我认为在StreamReader上调用dispose也必须杀死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)
    }
}

答案 1 :(得分:18)

是的,StreamReader将关闭提供的流。

如果您使用> v4.5,请使用StreamReader构造函数使流保持打开状态。

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

答案 2 :(得分:1)

您需要使用request filter。编写一个派生自Stream的类,并将其注册为过滤器。

答案 3 :(得分:1)

这个答案没有用。它返回一个包含空值的数组。

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

因为消耗了输入流。

答案 4 :(得分:1)

我必须对" cbp"提供的答案进行一些小调整。使用他的代码时,我只得零。我将位置设置为高于读数的0,现在它可以正常工作。

/var/www

答案 5 :(得分:-1)

某个时候,RequestFilter没有运行方法Read。似乎是W3WP不能通过正常的方式阅读httprequest的内容。

如果将WEbservice部署到服务器。然后使用IHttpModule来捕获它。添加RequestFilter

但RequestFilter的方法Read()不会运行:P