Web Api响应工作流

服务端

Http请求先到HOST中,Host转发给HttpServer(System.Net.Http)。封装请求改变请求为HttpRequestMessage(WebAPI的请求承载类)经过一系列的自定义的Handler来处理,这些handler串联成pipeline最后请求传递给HttpControllerDispatcher(检索路由表)转发到对应的Controller中的Action.

客户端

httpRequestMessage先到HttpClient中转到pipeline,传入到HttpClientHandler。转化为HttpRequest请求。

 

    class RequestUpHandler:DelegatingHandler
{
  protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,System.Threading.CancellationToken cancellationToken)
{
  request.Handers.Add("key","11234");
return base.SendAsync(request,cancellationToken);  
}         
}


注:

1.customhandler继承自DelegatingHandler类,上面已经说过,WebAPI的客户端和服务端被设计为相互对应的俩套结构,所以不论是在客户端还是在服务端,customhandler都是继承自DelegatingHandler类

2.DelegatingHandler的sendAsync方法便是处理请求和接受请求时会被调用的方法,该方法的返回值是HttpResponseMessage,接收的值为HttpRequestMesage,符合我们的一般认知

3.方法的最后,调用base.SendAsync是将Request继续向该pipeline的其它customHandler传递,并获取其返回值。由于该方法不包含Response的处理逻辑,只需直接将上一个CustomHandler的返回值返回即可。

 

static void Main(string []args)
{
  HttpClient client = new HttpClient(new RequestUpHandler(){ InnerHandler =new HttpClientHandler() });
  HttpResponseMessage response = client.GetAsync("http://localhost:90045/api/FormSubmit").Result;
  response.Content.ReadAsAsync<string>().ContinueWith((str)=>{Console.WriteLine(str.Result);});
  Console.Read();      
}

 客户端创建了一个HttpClient,HttpClient可以接受一个参数。该参数就是CustomHandler,此处我们嵌入了我们定义的RequestUpHandler,用于对Request报头进行嵌入身份验证码的处理,CustomHandler通过InnerHandler属性嵌入其内置的下一个CustomHandler,此处,由于没有下一个CustomerHandler,我们直接嵌入HttpClientHandler用于将HttpRequestMessage转化为Http请求,将Http响应转化为HttpResponseMessage

服务端

服务端的customHandler用于解析Http报头中的身份认证码

  protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            int matchHeaderCount = request.Headers.Count((item) =>
            {
                if ("key".Equals(item.Key))
                {
                    foreach (var str in item.Value)
                    {
                        if ("11234".Equals(str))
                            return true;
                    }
                }
                return false;
            });
            if (matchHeaderCount > 0) {
                return base.SendAsync(request, cancellationToken);
            }
            return Task.Factory.StartNew<HttpResponseMessage>(() => { return new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden); });
        }

 注:

如果身份验证通过,则通过base.SendAsync继续将请求向下传递,否则返回直接中断请求的传递,直接返回一个相应吗为403的响应,指示没有权限。

注意由于SendAsync的返回值需要封装在Task之中,所以需要使用Task.Factory.StartNew将返回值包含在Task中

将customHandler注入到HOST中

本例汇总WebAPI HOST在IIS上,所以我们只需将我们定义的CustomHandler在Application_Start中定义即可

 protected void Application_Start()
        {
            //省略其他逻辑代码

            GlobalConfiguration.Configuration.MessageHandlers.Add(new HttpUrlHandler());
        }

  

由于WebAPI Host在IIS上,所以HttpServer和HttpControllerDispatcher不用我们手工处理

 

posted @ 2016-04-22 15:51  海_洋  阅读(915)  评论(0)    收藏  举报