[Dry] .NET WebApi HttpMessageHandler pipeline

Original: [dry] .NET WebApi HttpMessageHandler pipeline

Message interceptor is a class that receives HTTP request and returns the HTTP response, Message handler inherits from the abstract class HttpMessageHandler, message filters before you learn that you should understand the flow of execution under webapi.

 

The above is the flow of execution webapi, first from the beginning of the implementation of response after an order by the network back to the Request, which after messageHandler, because it is the place webapi architecture can customize the handler to us, and this is almost the past webform. It is based on the http request.

Likely you will say it and filter Aop mode almost ah, but no matter how powerful than anyone else after you read this article, of course, it's useful both are different.

That message interceptor what use is it, I think you should listen to the name you know how it is, it is possible to request a modification request an intermediate layer information in a client where we can be made again; add response headers, reaching the controller before, a parameter validation!

Custom MessageHandler need to inherit  System.Net.Http.DelegatingHander and overloaded method SendAsync

?
1
2
3
4
5
6
7
8
9
10
11
public class MessageHandler1 : DelegatingHandler
{
   protected async override Task<HttpResponseMessage> SendAsync(
     HttpRequestMessage request, CancellationToken cancellationToken)
   {
     Debug.WriteLine( "hello" );
     var response = await base .SendAsync(request, cancellationToken);
     Debug.WriteLine( "bye" );
     return response;
   }
}

 This is the basic process flow, of course, since you need to add during configuration.

?
1
2
3
4
5
6
7
8
public static class WebApiConfig
{
   public static void Register(HttpConfiguration config)
   {
     config.MessageHandlers.Add( new MessageHandler1());
     config.MessageHandlers.Add( new MessageHandler2());
   }
}

 在消息拦截器中常见的是要判断用户信息,因为像ActionFilterAttribute、ApiControllerActionInvoker、ExceptionFilterAttribute 这些都是在action之前的,那我们就要在之前进行判断。

 在HttpRequestMessage中包含了以下属性,这些你都是可以改的。

 如何操作header?

?
1
2
3
4
5
6
7
protected async override Task<HttpResponseMessage> SendAsync(
      HttpRequestMessage request, CancellationToken cancellationToken)
        {
            HttpResponseMessage response = await base .SendAsync(request, cancellationToken);
            response.Headers.Add( "X-Custom-Header" , "This is my custom header." );
            return response;
        }

 首先调用sendAsync将请求传递给inner handler,让它返回响应信息,但是它在创建异步的时候,响应消息是不可用的。

只能全局去配置吗?

?
1
2
3
4
5
6
7
//路由中指定Message Handler
         config.Routes.MapHttpRoute(
             name: "Route2" ,
             routeTemplate: "api2/{controller}/{id}" ,
             defaults: new { id = RouteParameter.Optional },
             handler: new MessageHandler2() // per-route message handler
     );

这时MessageHandler2替换默认的HttpControllerDispatcher。这个栗子中MessageHandler2创建响应,匹配“Route2”的请求永远不会转到控制器。这使我们可以使用自己的自定义响应替换整个Web API控制器机制。

不知道你有没有想过,如果你的webapi不支持一些特殊的请求,你该怎么办呢,这个时候呵呵,你应该知道了吧!

在这个实例中我们定义了一个集合,在post请求中,一定不是get,那么就有可能是put 或者delete等待的请求头,那么我们可以获取进行修改。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MethodOverrideHandler : DelegatingHandler
         {
             readonly string [] _methods = { "DELETE" , "HEAD" , "PUT" };
             const string _header = "X-HTTP-Method-Override" ;
             protected override Task<HttpResponseMessage> SendAsync(
                 HttpRequestMessage request, CancellationToken cancellationToken)
             {
                 if (request.Method == HttpMethod.Post && request.Headers.Contains(_header))
                 {
                     var method = request.Headers.GetValues(_header).FirstOrDefault();
                     if (_methods.Contains(method, StringComparer.InvariantCultureIgnoreCase))
                     {
                         request.Method = new HttpMethod(method);
                     }
                 }
                 return base .SendAsync(request, cancellationToken);
             }
         }

  那我们可以获取请求头,如何进行添加呢??

?
1
2
3
4
5
6
7
8
9
10
public class CustomHeaderHandler : DelegatingHandler
{
     async protected override Task<HttpResponseMessage> SendAsync(
             HttpRequestMessage request, CancellationToken cancellationToken)
     {
         HttpResponseMessage response = await base .SendAsync(request, cancellationToken);
         response.Headers.Add( "X-Custom-Header" , "This is my custom-header." );
         return response;
     }
}

  在以上代码中我们通过base.SendAsync调用内部消息处理器返回相应结果,base.SendAsync之前是不可响应获取消息的。

  这个示例使用了await关键字,以便在SendAsync完成之后异步地执行任务。

?
1
2
3
4
5
6
7
8
9
10
11
12
protected override Task<HttpResponseMessage> SendAsync(
       HttpRequestMessage request, CancellationToken cancellationToken)
   {
       return base .SendAsync(request, cancellationToken).ContinueWith(
           (task) =>
           {
               HttpResponseMessage response = task.Result;
               response.Headers.Add( "X-Custom-Header" , "This is my custom header." );
               return response;
           }
       );
   }

Guess you like

Origin www.cnblogs.com/lonelyxmas/p/12052092.html