IIS 7托管模块无法获取Content-Length或发送的字节数

我有一个IIS 6的ISAPIfilter,它使用响应的字节发送字段进行一些自定义处理。 我想为IIS 7更新它,但我遇到了一个问题。 IIS 7事件似乎都没有访问内容长度,发送的字节数或任何可以让我计算发送的内容长度或字节数的数据。 (我知道内容长度标头和发送的字节不一样,但两者都可以用于此目的。)

据我所知,在托管模块完成执行后,HTTP.SYS添加了内容长度标头。 现在我有一个在EndRequest上运行的事件处理程序。 如果我可以得到输出流,我可以计算出我自己需要的东西,但托管管道似乎也无法访问。

是否有某种方法可以获取托管管道中发送的内容长度或字节数? 如果失败了,我是否可以通过某种方式计算托管管道中可用对象发送的内容长度或字节数?

要获取发送的字节,您可以使用HttpResponse.Filter属性。 正如MSDN文档所说,此属性获取或设置一个包装filter对象,用于在传输之前修改HTTP实体主体。

您可以创建一个新的System.IO.Stream ,它包装现有的HttpResponse.Filter流,并在传递它们之前计算传入Write方法的字节数。 例如:

 public class ContentLengthModule : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += OnBeginRequest; context.EndRequest += OnEndRequest; } void OnBeginRequest(object sender, EventArgs e) { var application = (HttpApplication) sender; application.Response.Filter = new ContentLengthFilter(application.Response.Filter); } void OnEndRequest(object sender, EventArgs e) { var application = (HttpApplication) sender; var contentLengthFilter = (ContentLengthFilter) application.Response.Filter; var contentLength = contentLengthFilter.BytesWritten; } public void Dispose() { } } public class ContentLengthFilter : Stream { private readonly Stream _responseFilter; public int BytesWritten { get; set; } public ContentLengthFilter(Stream responseFilter) { _responseFilter = responseFilter; } public override void Flush() { _responseFilter.Flush(); } public override long Seek(long offset, SeekOrigin origin) { return _responseFilter.Seek(offset, origin); } public override void SetLength(long value) { _responseFilter.SetLength(value); } public override int Read(byte[] buffer, int offset, int count) { return _responseFilter.Read(buffer, offset, count); } public override void Write(byte[] buffer, int offset, int count) { BytesWritten += count; _responseFilter.Write(buffer, offset, count); } public override bool CanRead { get { return _responseFilter.CanRead; } } public override bool CanSeek { get { return _responseFilter.CanSeek; } } public override bool CanWrite { get { return _responseFilter.CanWrite; } } public override long Length { get { return _responseFilter.Length; } } public override long Position { get { return _responseFilter.Position; } set { _responseFilter.Position = value; } } }