在 HttpModule 中读取 HTTP 请求体

Reading HTTP request body in HttpModule

我在 IIS 中有一个 .NET Core Web API 运行。我想在 POST 上的 IIS 日志中添加请求正文。因此,在 .NET Full Framework 中,我创建了 class 库,其中包含一个实现 IHttpModule 的 class。我必须使用 .NET Full Framework,因为 IHttpModule 不在 Core 中。

我的问题是请求InputStream只能读取一次。因此,当我在我的代码中读取它时,流到达我的核心 API 时已经结束(并且 Stream 对象已被修改)。我已经尝试了所有我能想到的并且我已经搜索了很多。

什么不起作用:

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

是的,我得到了正文,但流位置没有重置。重置位置没有帮助。

var reader = new StreamReader(HttpContext.Current.Request.InputStream, Encoding.UTF8, true, 1024, true);
HttpContext.Current.Request.InputStream.Position = 0;

最后一个标志应该告诉流保持打开状态,但对核心的调用仍然失败。

context.HttpContext.Request.Body

在标准 .NET 中不可用。

然后我试了这个:

var s2 = new MemoryStream(request.TotalBytes);
HttpContext.Current.Request.InputStream.CopyTo(s2);

还是失败了。即使是这个小代码也会使它失败:

var v = request.TotalBytes;

到目前为止我的想法

查看流的源代码我可以看到它的一些内部数据在读取属性时发生了变化,所以我的想法是 IIS 确保消息之前没有被篡改将其发送给 Kestrel。任何人都可以阐明这一点吗?也许你知道另一个人完成了这个任务?

旁注: 是的,我可以使用其他 IIS 模块以其他方式获取正文消息,但他们不会将其放入标准 IIS 日志中,而是创建自己的自己的。我已经将 IIS 登录到我的 ELK 堆栈中,这就是为什么这样会更容易。

有点晚了,但我也处理了好几个小时。终于得到了使用

的解决方案
request.GetBufferedInputStream()

改为

request.InputStream

(.NET Framework 4.6)