18

在 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 ,对我没有帮助。

4

3 回答 3

24

在这里,您正在创建一个HttpMessageHandler哪些短路请求并且不让请求通过管道的其余部分。相反,您应该创建一个DelegatingHandler.

Web API 中还有 2 种消息处理程序管道。一种是常规管道,其中所有路由的所有请求都通过,另一种可能具有特定于某些路由的消息处理程序。

  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()})
                );
    

此 Web Api 海报显示了管道流程。

于 2013-03-04T17:25:36.693 回答
14

要编写自定义消息处理程序,您应该从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将请求发送到内部处理程序。

于 2013-03-04T15:02:19.693 回答
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;
        }
}
于 2020-12-20T12:59:25.093 回答