如何在Web API中实现HttpMessageHandler?

时间:2013-03-04 14:48:38

标签: c# asp.net-mvc-4 asp.net-web-api asp.net-4.5

在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,对我不起作用。

3 个答案:

答案 0 :(得分:22)

在这里,您要创建一个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()})
                );
    
  3. 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;
        }
}