如何在ASP.net Web API控制器中获取响应长度?

时间:2013-12-18 01:44:25

标签: asp.net-web-api

在WEBAPI过滤器中,我试图计算响应大小。 类似的过程适用于MVC控制器。

在actionExecutedContext.Response中。我看不到过滤器?

所以我在下面尝试了这个过滤器,但这不起作用。

如何获得WEBApi响应的长度? 我可以在Global.ASAX中使用它并且它可以工作,但是每次http调用都会记录下来...... 所以API过滤器是理想的。这里有什么明显的错误吗?

public class BosAPIFilter : System.Web.Http.Filters.ActionFilterAttribute{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) {
        base.OnActionExecuted(actionExecutedContext);
        var httpContext = actionExecutedContext.Request.Properties["MS_HttpContext"] as HttpContextWrapper;
        if (httpContext != null) {
        actionExecutedContext.Response.
            httpContext.Response.Filter = new ResponseStreamHandler(httpContext.Response.Filter);
            var handler = httpContext.Response.Filter as ResponseStreamHandler;
            var adminService = new AdminServices();
            adminService.HttpTrace(httpContext, handler);
        }
    }


 public class ResponseStreamHandler : MemoryStream {
    private readonly Stream _responseStream;
    public long ResponseSize { get; private set; }

    public ResponseStreamHandler(Stream responseStream) {
        this._responseStream = responseStream;
        ResponseSize = 0;
    }

    public override void Write(byte[] buffer, int offset, int count) {
        this.ResponseSize += count;
        this._responseStream.Write(buffer, offset, count);
    }


    // ReSharper disable once RedundantOverridenMember
    public override void Flush() { base.Flush(); }
}

1 个答案:

答案 0 :(得分:1)

在ASP.NET Web API管道中,操作过滤器在从action方法返回的结果被序列化之前运行。如果您在过滤器中查看actionExecutedContext.Response.Content,它将为System.Net.Http.ObjectContent(取决于您的操作方法)。因此,您可以稍后在管道中计算响应大小。您可以使用消息处理程序执行此操作,但粒度不在操作方法级别。您可以获得的最低粒度是在路由级别。解决此问题的一种方法是在过滤器中设置请求字典中的标志,并仅在设置标志时从处理程序中记录。