如何在Web API中实现HttpMessageHandler?

Toh*_*hid 16 c# asp.net-mvc-4 asp.net-4.5 asp.net-web-api

在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()
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我发展了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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Kir*_*lla 22

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

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

  1. 尝试创建一个DelegatingHandler并将其添加到您HttpConfiguration的消息处理程序列表中:

    config.MessageHandlers.Add(new HandlerA())
    
    Run Code Online (Sandbox Code Playgroud)
  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()})
                );
    
    Run Code Online (Sandbox Code Playgroud)

此Web Api海报显示管道流程.


cuo*_*gle 11

要编写自定义消息处理程序,您应该派生自 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Cuonge Le - 谢谢你的回答.在用你的代码替换`CustomMessageHandler`后,它会在`return base.SendAsync(request,cancellationToken)上引发错误;`说:**尚未分配内部处理程序.**.我又错过了什么? (3认同)