Преобразование HttpRequestMessage в OwinRequest и OwinResponse в HttpResponseMessage

У меня есть обработчик сообщений веб-API MyHandler, который я хочу запустить в конвейере OWIN в качестве промежуточного программного обеспечения. Итак, настройте обработчик следующим образом.

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseHttpMessageHandler(new MyHandler());

        HttpConfiguration config = new HttpConfiguration();

        config.Routes.MapHttpRoute(
            "DefaultWebApi",
                "{controller}/{id}",
                    new { id = RouteParameter.Optional });

        app.UseWebApi(config);
    }
}

Обработчик очень простой и ничего не делает.

public class MyHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
             HttpRequestMessage request, CancellationToken cancellationToken)
    { // <--- breakpoint here

        var response = await base.SendAsync(request, cancellationToken);
        return response;
    }
}

Я поставил точку останова внутри SendAsync, и он сломался, но следующие base.SendAsync молча взрываются, и я вижу A first chance exception of type 'System.InvalidOperationException' occurred in System.Net.Http.dll.

Я могу довольно легко добавить MyHandler к config.MessageHandlers, и он будет отлично работать в конвейере веб-API, но это не то, что я хочу делать. Я хочу запустить MyHandler в конвейере OWIN. Это вообще возможно? Так должно быть. В противном случае, я думаю, нет смысла иметь метод расширения UseHttpMessageHandler. Просто я не мог придумать, как делать то, что я хочу делать.


person Badri    schedule 15.07.2013    source источник
comment
Я думаю, вы путаете понятия обработчиков сообщений и обработчиков делегирования. Обработчик сообщений — это просто то, что принимает запрос и возвращает ответ.   -  person Youssef Moussaoui    schedule 16.07.2013
comment
Я понимаю разницу между обработчиком сообщений и делегирующим обработчиком. Обработчик делегирования — это обработчик сообщений, и я просто надеялся, что смогу использовать обработчик делегирования вместо обработчика сообщений, и волшебным образом он будет работать в конвейере OWIN, как он работает в конвейере веб-API, и, по-видимому, это невозможно. , на основе ответа Киран. Согласен, я слишком амбициозен. Спасибо, что посмотрели мой вопрос.   -  person Badri    schedule 16.07.2013


Ответы (1)


Да, этот опыт нужно улучшить, так как исключение молча игнорируется.

Для вашего вышеприведенного сценария вам нужно будет получить от HttpMessageHandler вместо DelegatingHandler, поскольку обработчик делегирования попытается делегировать запрос обработчикам после него (пример: в исключении упоминается Message=The inner handler has not been assigned)

Например, будет работать следующее:

appBuilder.UseHttpMessageHandler(new MyNonDelegatingHandler());

public class MyNonDelegatingHandler : HttpMessageHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage();
        response.Content = new StringContent("Hello!");

        return Task.FromResult<HttpResponseMessage>(response);
    }
}

А для создания цепочки обработчиков можно сделать следующее:

appBuilder.UseHttpMessageHandler(HttpClientFactory.CreatePipeline(innerHandler: new MyNonDelegatingMessageHandler(),
           handlers: new DelegatingHandler[] { new DelegatingHandlerA(), new DelegatingHandlerB() }));
person Kiran Challa    schedule 15.07.2013
comment
Спасибо, это немного проясняет. Последний вопрос. Можно ли только HttpMessageHandler превратить в промежуточное ПО OWIN с помощью адаптера? Я надеялся, что мы сможем сделать что-то подобное и для делегирования обработчиков. В моем случае мне также нужно посмотреть ответное сообщение. - person Badri; 15.07.2013
comment
Понимаю. Для некоторой ясности два расширения UseWebApi подключают HttpServer, а расширение UseHttpMessageHandler не подключает его и дает вам возможность построить конвейер, как я упоминал в посте. Теперь, что касается вашего вопроса о просмотре ответа, я думаю, вам нужно подключить общее промежуточное ПО OWIN, где вы можете проверить ответ, а не HttpMessageHandler. Тогда конвейер запросов будет выглядеть так: ->MyOwinInspectorMiddleware->HttpMessageHandlerAdapter->HttpServer(HandlerA -> HanlerB -> etc) - person Kiran Challa; 15.07.2013
comment
@KiranChalla Привет, где это расширение UseHttpMessageHandler? Я не могу найти его в источнике Katana. - person Aliostad; 05.08.2013
comment
@Aliostad: это часть System.Web.Http.Owin - person Kiran Challa; 05.08.2013