C# 如何在 Web API 中实现 HttpMessageHandler?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15204257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:27:43  来源:igfitidea点击:

How to implement HttpMessageHandler in Web API?

c#asp.net-mvc-4asp.net-web-apiasp.net-4.5

提问by Tohid

In an ASP.NET 4.5 MVC 4 Web API project, I want to add a custom HttpMessageHandler. I've changed WebApiConfigclass (in \App_Satrt\WebApiConfig.cs), as follows:

在 ASP.NET 4.5 MVC 4 Web API 项目中,我想添加一个自定义HttpMessageHandler. 我已经更改了WebApiConfig类(在 \App_Satrt\WebApiConfig.cs 中),如下所示:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: null,
            handler: new MyCustomizedHttpMessageHandler()
        );
    }
}

Then I developed MyCustomizedHttpMessageHandler:

然后我开发MyCustomizedHttpMessageHandler

public class MyCustomizedHttpMessageHandler : HttpMessageHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        IPrincipal principal = new GenericPrincipal(
            new GenericIdentity("myuser"), new string[] { "myrole" });
        Thread.CurrentPrincipal = principal;
        HttpContext.Current.User = principal;

        return Task<HttpResponseMessage>.Factory.StartNew(() => request.CreateResponse());
    }
}

However, the request to the API (let's say http://mylocalhost.com/api/values), always returns status code 200, without any data. I mean it never gets to ValuesController.cs's 'GET()' method.

但是,对 API 的请求(比方说 http://mylocalhost.com/api/values)总是返回状态代码 200,没有任何数据。我的意思是它永远不会到达 ValuesController.cs 的 'GET()' 方法。

What have I missed? How can I implement HttpMessageHandlerproperly?

我错过了什么?我该如何HttpMessageHandler正确实施?

PS: Have already read this one: https://stackoverflow.com/a/12030785/538387, doesn't help me.

PS:已经读过这个:https: //stackoverflow.com/a/12030785/538387,对我没有帮助。

采纳答案by Kiran Challa

Here you are creating a HttpMessageHandlerwhich short circuits the request and doesn't let the request pass through the rest of the pipeline. Instead, you should create a DelegatingHandler.

在这里,您将创建一个HttpMessageHandler短路请求,并且不让请求通过管道的其余部分。相反,您应该创建一个DelegatingHandler.

Also there are 2 kinds of message handler pipelines in Web API. One is a regular pipeline in which all requests for all routes pass through and other where one could have message handlers specific to certain routes only.

Web API 中还有 2 种消息处理程序管道。一种是常规管道,其中所有路由的所有请求都通过,另一种是可以具有特定于某些路由的消息处理程序。

  1. Try to create a DelegatingHandlerand add it to your HttpConfiguration's list of message handlers:

    config.MessageHandlers.Add(new HandlerA())
    
  2. If you want to add a route specific message handler, then you could do the following:

    config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional },
                constraints: null,
                handler: 
                       HttpClientFactory.CreatePipeline(
                              new HttpControllerDispatcher(config), 
                              new DelegatingHandler[]{new HandlerA()})
                );
    
  1. 尝试创建一个DelegatingHandler并将其添加到您HttpConfiguration的消息处理程序列表中:

    config.MessageHandlers.Add(new HandlerA())
    
  2. 如果要添加特定于路由的消息处理程序,则可以执行以下操作:

    config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional },
                constraints: null,
                handler: 
                       HttpClientFactory.CreatePipeline(
                              new HttpControllerDispatcher(config), 
                              new DelegatingHandler[]{new HandlerA()})
                );
    

This Web Api Postershows the pipeline flow.

此 Web Api 海报展示了管道流程。

回答by cuongle

To write a custom message handler, you should derive from System.Net.Http.DelegatingHandler

要编写自定义消息处理程序,您应该从 System.Net.Http.DelegatingHandler

class CustomMessageHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> 
      SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        IPrincipal principal = new GenericPrincipal(
            new GenericIdentity("myuser"), new string[] { "myrole" });
        Thread.CurrentPrincipal = principal;
        HttpContext.Current.User = principal;

        return base.SendAsync(request, cancellationToken);
    }
}

And call base.SendAsyncto send the request to the inner handler.

并调用base.SendAsync将请求发送到内部处理程序。