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
How to implement HttpMessageHandler in Web API?
提问by Tohid
In an ASP.NET 4.5 MVC 4 Web API project, I want to add a custom HttpMessageHandler
. I've changed WebApiConfig
class (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 HttpMessageHandler
properly?
我错过了什么?我该如何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 HttpMessageHandler
which 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 种消息处理程序管道。一种是常规管道,其中所有路由的所有请求都通过,另一种是可以具有特定于某些路由的消息处理程序。
Try to create a
DelegatingHandler
and add it to yourHttpConfiguration
's list of message handlers:config.MessageHandlers.Add(new HandlerA())
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()}) );
尝试创建一个
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 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.SendAsync
to send the request to the inner handler.
并调用base.SendAsync
将请求发送到内部处理程序。