【问题标题】:No Response Header in DelegatingHandlerDelegatingHandler 中没有响应头
【发布时间】:2013-08-24 19:02:46
【问题描述】:

我正在尝试记录我的 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.Currentnull

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

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

【问题讨论】:

  • 这里有同样的问题。你有解决办法吗?
  • 不,从未发现
  • 我通过将响应标头发送到客户端而不是更改委托处理程序中的响应消息来解决了这个问题。在我的 javascript 框架中也容易得多!

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


【解决方案1】:

消息处理程序的调用顺序与它们出现的顺序相同 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

【讨论】:

    【解决方案2】:

    试试下面的代码。

    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;
                            }
                );
    

    【讨论】:

    【解决方案3】:

    你必须看对地方:

    request.Content.Headers.ContentType
    

    假设有一个Content-Type: application/json 请求头,那么前面提到的将返回"application/json"

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

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

    response.Content.Headers.ContentType
    

    【讨论】:

    • 不会得到 request 标头吗?我需要记录所有响应标头,不仅是 ContentType,而且 response.Headers 为空
    • 同样的事情:response.Content.Headers
    • response.Content.Headers 仅包含 ContentType。 iis express是否添加了其他标头(内容长度,缓存等),因此无法获取它们?
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 2018-02-25
    • 1970-01-01
    相关资源
    最近更新 更多