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

cbp*_*cbp 31 .net inputstream httpmodule

我正在尝试使用像这样的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)
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,在将输入流读取到结尾后,InputStream似乎已消失或更有可能,光标位于流的末尾.

我尝试过request.InputStream.Position = 0;,request.InputStream.Seek(0, SeekOrigin.Begin);但都没有工作.

cbp*_*cbp 40

我已经解决了这个问题:我认为在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);
Run Code Online (Sandbox Code Playgroud)

那么完整的代码:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 注意那里的编码,我想你会希望它是Encoding.UTF8.GetString(bytes); (7认同)

Iva*_*ton 19

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

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

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