6

I have a web API message handler MyHandler that I want to run in OWIN pipeline as a middleware. So configuring the handler like this.

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

Handler is very simple and does nothing.

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

I put a break point inside SendAsync and it does break but the following base.SendAsync bombs silently and I see A first chance exception of type 'System.InvalidOperationException' occurred in System.Net.Http.dll.

I can quite easily add MyHandler to config.MessageHandlers and it will run perfect in the Web API pipeline but that's not what I want to do. I want to run MyHandler in the OWIN pipeline. Is this possible at all? It should be. Otherwise, there is no point in having the extension method UseHttpMessageHandler, I guess. Just that I couldn't figure out a way to do what I want to do.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • I think you're confusing the concepts of message handlers and delegating handlers. A message handler is just something that takes a request and returns a response. – Youssef Moussaoui Jul 16 '13 at 05:22
  • I do understand the difference between message handler and a delegating handler. A delegating handler is a message handler and I was just hoping that I will be able to use a delegating handler in place of message handler and magically it will run in the OWIN pipeline like it runs in a Web API pipeline and apparently it is not possible, based on Kiran's reply. I agree I'm too ambitious. Thanks for looking at my question. – Badrinarayanan Lakshmiraghavan Jul 16 '13 at 14:17

1 Answers1

1

Yeah, this experience needs to be improved as the exception is silently ignored.

For your above scenario, you would need to derive from HttpMessageHandler instead of DelegatingHandler as the delegating handler would try to delegate the request to handlers after it.(example: The exception mentions Message=The inner handler has not been assigned)

For example, the following would work:

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

And for creating a chain of handlers, you could do the following:

appBuilder.UseHttpMessageHandler(HttpClientFactory.CreatePipeline(innerHandler: new MyNonDelegatingMessageHandler(),
           handlers: new DelegatingHandler[] { new DelegatingHandlerA(), new DelegatingHandlerB() }));
Kiran
  • 56,921
  • 15
  • 176
  • 161
  • Thanks, this clarifies quite a bit. One final question. Can only `HttpMessageHandler` be turned into an OWIN middleware using the adapter? I was hoping we could something like that for delegating handlers too. In my case, I need to look at the response message too. – Badrinarayanan Lakshmiraghavan Jul 15 '13 at 16:00
  • I see. For some clarity, the two `UseWebApi` extensions hookup a `HttpServer` and the `UseHttpMessageHandler` extension doesn't hookup it and gives you the options of building a pipeline like i mentioned in the post. Now coming to your question about looking at the response, I think you would need to hook in a general OWIN middleware where you can inspect the response and not a HttpMessageHandler. The request pipeline would then look like : `->MyOwinInspectorMiddleware->HttpMessageHandlerAdapter->HttpServer(HandlerA -> HanlerB -> etc)` – Kiran Jul 15 '13 at 16:17
  • @KiranChalla Hi, where is this `UseHttpMessageHandler` extension? I cannot find it in Katana source. – Aliostad Aug 04 '13 at 21:42
  • @Aliostad: its part of System.Web.Http.Owin – Kiran Aug 04 '13 at 21:56