如何在Web API中实现HttpMessageHandler?

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

然后我开发了MyCustomizedHttpMessageHandler

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

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

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

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

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

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

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

这个Web Api Poster显示了管道流程。

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

 class CustomMessageHandler : DelegatingHandler { protected override Task 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); } } 

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