【问题标题】:Converting HttpRequestMessage to OwinRequest and OwinResponse to HttpResponseMessage将 HttpRequestMessage 转换为 OwinRequest 并将 OwinResponse 转换为 HttpResponseMessage
【发布时间】:2013-07-13 10:12:24
【问题描述】:

我有一个 Web 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);
    }
}

Handler 很简单,什么也不做。

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,它会在Web API 管道中完美运行,但这不是我想要做的。我想在 OWIN 管道中运行 MyHandler。这有可能吗?它应该是。否则,我猜,扩展方法UseHttpMessageHandler 毫无意义。只是我想不出一种方法来做我想做的事。

【问题讨论】:

  • 我认为您混淆了消息处理程序和委托处理程序的概念。消息处理程序只是接受请求并返回响应的东西。
  • 我明白消息处理程序和委托处理程序之间的区别。委托处理程序是一个消息处理程序,我只是希望我能够使用委托处理程序代替消息处理程序,并且神奇地它将在 OWIN 管道中运行,就像它在 Web API 管道中运行一样,显然这是不可能的,基于基兰的回复。我同意我野心太大。感谢您查看我的问题。

标签: c# asp.net-web-api owin katana


【解决方案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() }));

【讨论】:

  • 谢谢,这澄清了很多。最后一个问题。只能使用适配器将HttpMessageHandler 变成OWIN 中间件吗?我希望我们也可以为委托处理程序提供类似的东西。就我而言,我也需要查看响应消息。
  • 我明白了。为了清楚起见,两个UseWebApi 扩展连接了HttpServerUseHttpMessageHandler 扩展并没有连接它,而是为您提供了构建管道的选项,就像我在帖子中提到的那样。现在谈到您关于查看响应的问题,我认为您需要连接一个通用的 OWIN 中间件,您可以在其中检查响应而不是 HttpMessageHandler。请求管道将如下所示:-&gt;MyOwinInspectorMiddleware-&gt;HttpMessageHandlerAdapter-&gt;HttpServer(HandlerA -&gt; HanlerB -&gt; etc)
  • @KiranChalla 嗨,这个UseHttpMessageHandler 分机在哪里?我在 Katana 源中找不到它。
  • @Aliostad:它是 System.Web.Http.Owin 的一部分
猜你喜欢
  • 2018-01-27
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-27
  • 2013-05-10
  • 2020-09-28
相关资源
最近更新 更多