DelegatingHandler中没有响应标头

时间:2013-08-22 07:07:54

标签: c# asp.net asp.net-mvc-4 asp.net-web-api web-api-contrib

我正在尝试记录我的Web API项目的HTTP响应标头。

该项目由VS2012,.NET 4.5和ASP.NET MVC 4开发。

我写了这样一个DelegatingHandler子类:

public class LoggingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {

        // Execute the request
        return base.SendAsync(request, cancellationToken).ContinueWith(task =>
        {
            var response = task.Result;
            return response;
        });
    }
}

然而,问题是,我无法从response获取标头值。 response.Headers是一个空集合,response.Content.Headers只包含一个名为Content-Type的密钥,而HttpContext.Current只有null

我已经看到WebAPIContrib的代码使用相同的逻辑来记录标题,但它们的代码似乎也不起作用。

那么我该如何跟踪Web API项目中的HTTP响应标头?

2 个答案:

答案 0 :(得分:3)

  

消息处理程序的调用顺序与它们出现的顺序相同   MessageHandlers集合。因为它们是嵌套的,所以响应   消息向另一个方向传播。也就是说,最后一个处理程序是   第一个收到回复消息。

确保在管道的早期注册了日志记录处理程序。首选。

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        config.MessageHandlers.Add(new LoggingHandler(...));

        //...add other handlers
        config.MessageHandlers.Add(new MessageHandler1());
        config.MessageHandlers.Add(new MessageHandler2());

        // Other code not shown...
    }
}

这样任何其他处理程序都有机会填充响应并记录该信息。

您还可以使用async / await语法简化类,以便更清楚地访问响应。

public class LoggingHandler : DelegatingHandler {
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {

        //...Extract and log request
        LogRequest(request);

        // Send the request on to the inner handler(s) and get the response
        var response = await base.SendAsync(request, cancellationToken);

        //...Extract details from response for logging
        LogResponse(response);

        return response;
    }

    private void LogRequest(HttpRequestMessage request) {
        //... code removed for brevity
    }

    private void LogResponse(HttpResponseMessage response) {
        //... code removed for brevity
    }
}

应该能够在返回之前从响应中访问必要的详细信息。

参考:HTTP Message Handlers in ASP.NET Web API

答案 1 :(得分:0)

你必须看正确的地方:

request.Content.Headers.ContentType

假设有一个Content-Type: application/json请求标头,那么上述内容将返回"application/json"

所以基本上一些标题与内容相关联,这就是你应该从中读取它们的地方。

响应标头也是如此。根据其类型,您可能需要从响应内容中提取它们(对于返回正文的请求)

response.Content.Headers.ContentType