Нет заголовка ответа в DelegatingHandler

Я пытаюсь зарегистрировать HTTP-заголовки ответа моего проекта Web API.

Проект разработан 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, который использует ту же логику для регистрации заголовков, но их код тоже не работает.

Итак, как я должен отслеживать заголовки ответа HTTP в проекте веб-API?

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 в ASP.NET Web API

Попробуйте приведенный ниже код.

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

Вы должны посмотреть в нужном месте:

request.Content.Headers.ContentType

Предполагая, что есть Content-Type: application/json заголовок запроса, тогда вышеупомянутый вернет "application/json",

Так что в основном некоторые заголовки связаны с контентом, и именно здесь вы должны их читать.

То же самое верно для заголовков ответа. В зависимости от их типа вам может потребоваться извлечь их из содержимого ответа (для запросов, возвращающих тело)

response.Content.Headers.ContentType
Другие вопросы по тегам