C# DelegatingHandler中没有响应标头

C# DelegatingHandler中没有响应标头,c#,asp.net,asp.net-mvc-4,asp.net-web-api,web-api-contrib,C#,Asp.net,Asp.net Mvc 4,Asp.net Web Api,Web Api Contrib,我正在尝试记录我的Web API项目的HTTP响应头 该项目由VS2012、.NET4.5和ASP.NETMVC4开发 我编写了一个DelegatingHandler子类,如下所示: public class LoggingHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationTok

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

该项目由VS2012、.NET4.5和ASP.NETMVC4开发

我编写了一个
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;
        });
    }
}
公共类日志处理程序:DelegatingHandler
{
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
//执行请求
返回base.sendaync(请求,取消令牌).ContinueWith(任务=>
{
var response=task.Result;
返回响应;
});
}
}
但是,问题是,我无法从
响应中获取标题值
response.Headers
是一个空集合,
response.Content.Headers
只包含一个名为
Content-Type
的键和
HttpContext。当前的
null

我见过使用相同逻辑记录头的代码,但它们的代码似乎也不起作用


那么,我应该如何在Web API项目中跟踪HTTP响应头呢?

您必须查看正确的位置:

request.Content.Headers.ContentType
假设有一个
内容类型:application/json
请求头,那么前面提到的将返回
“application/json”

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

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


请尝试下面的代码

return base.SendAsync(request, cancellationToken).ContinueWith(
                        task =>
                        {

                            var headers = task.Result.ToString();
                            var body = task.Result.Content.ReadAsStringAsync().Result;

                            // RETURN THE ORIGINAL RESULT
                            var response = task.Result;
                            return response;
                        }
            );
消息处理程序的调用顺序与它们在
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
    }
}
公共类日志处理程序:DelegatingHandler{
受保护的覆盖异步任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken){
//…提取和记录请求
日志请求(请求);
//将请求发送到内部处理程序并获取响应
var response=await base.sendaync(请求、取消令牌);
//…从响应中提取详细信息以进行日志记录
对数响应(响应);
返回响应;
}
私有无效日志请求(HttpRequestMessage请求){
//…为简洁起见,删除了代码
}
专用无效日志响应(HttpResponseMessage响应){
//…为简洁起见,删除了代码
}
}
应该能够在返回响应之前访问响应中的必要详细信息


参考资料:

这里也有同样的问题。您有解决方案吗?没有,从未发现OUT我通过将响应头发送到客户端而不是更改委托处理程序中的响应消息来解决问题。在我的javascript框架中也更容易!那不会得到请求头吗?我需要记录所有响应标题,不仅仅是ContentType,还有response。标题是emptySame:
response.Content.headers
response.Content.headers只包含ContentType。iis express是否添加了其他标头(内容长度、缓存等),因此无法获取它们?这与此处的第二个示例类似:
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
    }
}