在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<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://stackoverflow.com/a/12030785/538387,对我不起作用。
答案 0 :(得分:22)
在这里,您要创建一个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()})
);
This Web Api Poster显示了管道流程。
答案 1 :(得分: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);
}
}
并调用base.SendAsync
将请求发送给内部处理程序。
答案 2 :(得分:0)
我使用@cuongle 答案来解决我的问题。只需添加一项。所以我没有得到“尚未分配内部处理程序。”。谢谢@coungle。
public class CustomMessageHandler : DelegatingHandler
{
public CustomMessageHandler ()
{
//add this to solve "The inner handler has not been assigned"
InnerHandler = new HttpClientHandler();
}
protected override async Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Before request
IPrincipal principal = new GenericPrincipal(
new GenericIdentity("myuser"), new string[] { "myrole" });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
var result = await base.SendAsync(request, cancellationToken);
// After request when response arrives
return result;
}
}