如何在Web API中实现HttpMessageHandler?
在ASP.NET 4.5 MVC 4 Web API项目中,我想添加一个自定义HttpMessageHandler
。我已经改变了WebApiConfig
类(在\ App_Satrt \ WebApiConfig.cs),具体如下:如何在Web API中实现HttpMessageHandler?
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<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());
}
}
然而,请求API(假设http://mylocalhost.com/api/values) ,总是返回状态码200,没有任何数据。我的意思是它永远不会去ValuesController.cs的'GET()'方法。
我错过了什么?我如何正确实施HttpMessageHandler
?
PS:已经看过这个:https://*.com/a/12030785/538387,不帮我。
在这里,您正在创建一个HttpMessageHandler
,它将请求短路并且不让请求通过管道的其余部分。相反,您应该创建一个DelegatingHandler
。
在Web API中还有2种消息处理程序管道。一个是所有路由的所有请求都经过的常规管道,另一个可能只有特定路由的消息处理程序。
-
尝试创建一个
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()}) );
This Web Api Poster显示pipeli ne流动。
要编写自定义消息处理程序,您应该从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);
}
}
派生并呼吁base.SendAsync
发送请求到内部处理程序。
@Cuonge Le - 谢谢你的回答。在我用你的代码替换了'CustomMessageHandler'后,它在'return base.SendAsync(request,cancellationToken);'上说错误:**内部处理程序没有被赋值。我又错过了什么? – Tohid 2013-03-04 17:27:16
@Counge Le - 你的答案和Kirran Chall's的结合已经解决了这个问题。再次感谢你。 – Tohid 2013-03-04 17:57:34
@Cong Le .NET 4.0的等价物是什么?我无法找到.NET .4的DelegatingHandler ...如何在4.0中执行消息处理。谢谢你的帮助。 – jaxxbo 2013-05-22 15:06:05
谢谢。解决方案(1)运行良好。但数字2,'新HttpControllerDispatcher()'说:** System.Web.Http.Dispatcher.HttpControllerDispatcher不包含一个构造函数,它需要0个参数** - 更新:我修复了您的代码。谢谢。 – Tohid 2013-03-04 17:43:28
我更新了我的上述帖子too.thanks。 – 2013-03-04 18:25:29
请将Cuong Le的回答添加到回答中:**要编写自定义消息处理程序,您应该从'System.Net.Http.DelegatingHandler'派生** – Tohid 2013-03-04 18:37:43