如何在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中还有两种消息处理程序管道。 一个是常规管道,其中所有路由的所有请求都通过,而另一个管道可以只有特定于某些路由的消息处理程序。
-
尝试创建
DelegatingHandler
并将其添加到HttpConfiguration
的消息处理程序列表中:config.MessageHandlers.Add(new HandlerA())
-
如果要添加特定于路由的消息处理程序,则可以执行以下操作:
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
将请求发送到内部处理程序。