Skip to content

WebApiClient高级

老九 edited this page Sep 19, 2018 · 33 revisions

1. IHttpHanlder接口

WebApiClient将HttpMessageHandler类型包装IHttpHanlder类型,提供统一的接口操作方式。HttpMessageHandler的具体可能为HttpClientHandler、SocketsHttpHandler或DelegatingHandler,IHttpHanlder的SourceHandler属性为被包装的对象的本身。你可以从HttpApiConfig的HttpHandler属性获取IHttpHanlder实例,从而对其进行必要的一些设置。

2. IHttpClient

从0.2.0版本开始,IHttpClient接口被移除,其默认实现类WebApiClient.Defaults.HttpClient也被移除。原来的HttpApiConfig的HttpClient属性从IHttpClient类型变为System.Net.Http.HttpClient类型,HttpApiClient.HttpClient.Handler访问方式变为HttpApiClient.HttpHandler。之所以这么变更,是因为Handler属性在实际应用当中很少访问到,变更之后访问HttpHanlder的性能不变,但new HttpApiClient(System.Net.Http.HttpClient)的性能得到很多改善,因为这一步已经不包含包装为IHttpHandler的逻辑。

3. 扩展JsonFormatter

HttpApiConfig的JsonFormatter属性,默认为WebApiClient.Defaults.JsonFormatter。你可以派生WebApiClient.Defaults.JsonFormatter,重写CreateSerializerSettings方法,修改返回的JsonSerializerSettings;也可以自己实现IJsonFormatter接口,需要注意的是,需要考虑兼容DataAnnotations里面的几个特性,最后,实例化自定义的IJsonFormatter实现类,赋值到HttpApiConfig:

var config = new HttpApiConfig
{
    JsonFormatter = new MyJsonFormatter()
};
var client = HttpApiClient.Create<IMyWebApi>(config);

4. 扩展KeyValueFormatter

HttpApiConfig的KeyValueFormatter属性,默认为WebApiClient.Defaults.KeyValueFormatter。KeyValueFormatter是由Json.net扩展实现,Json.net能序列化为Json的对象,都可以被KeyValueFormatter序列化为KeyValuePair<string,string>集合。有关KeyValueFormatter的相关扩展,实际上为Json.net的扩展,最常见的比如自定义JsonConverter。

5. 扩展WebApiClient.Defaults.ApiInterceptor

ApiInterceptor是默认实现的IApiInterceptor,用于拦截http接口的调用,通过实现IApiInterceptor接口或派生WebApiClient.Defaults.ApiInterceptor,可以加入自己的拦截逻辑:

class MyApiInterceptor : WebApiClient.Defaults.ApiInterceptor
{
    public MyApiInterceptor(HttpApiConfig config)
        : base(config)
    {
    }

    public override object Intercept(object target, MethodInfo method, object[] parameters)
    {
        Console.WriteLine($"正在请求方法{method.Name}");
        return base.Intercept(target, method, parameters);
    }

    protected override ApiActionDescriptor GetApiActionDescriptor(MethodInfo method, object[] parameters)
    {
        return base.GetApiActionDescriptor(method, parameters);
    }
}

var config = new HttpApiConfig();
var apiInerceptor = new MyApiInterceptor(config);
var client = HttpApiClient.Create(typeof(IMyWebApi), apiInerceptor) as IMyWebApi;

6. 自定义业务异常、异常抛出和异常捕获处理

WebApiClient是不带业务性质的http客户端库,对于实际项目应用中,你可能会将服务器的一些响应情况,归类为对应的业务异常,常见的有种方式:

  • 使用Http状态码来标记业务异常
  • 统一返回200状态,在回复内容使用自定义业务状态码

不管是哪一种,客户端都需要根据不同的状态码执行一些业务规则逻辑,在WebApiClient使用中,可以将那些业务上任务异常的状态码转换为对应的自定义Exception,并抛出这些自定义Exception,将状态码转换为自定义的Exception,可以使用两种方式实现:

  • 继承ApiActionFilterAttribute创建一个Filter,重写OnEndRequestAsync方法,根据Http状态码或业务状态码创建自定义业务Exception并抛出,然后将Filter应用到全局过滤器或修饰在接口或修饰在接口的方法上。
  • 继承AutoReturnAttribute或ApiReturnAttribute,重写GetTaskResult方法,根据Http状态码或业务状态码创建自定义业务Exception并抛出,然后修饰在接口或修饰在接口的方法上。

使用ITask<>的Retry扩展方法捕获自定义业务Exception并实现重试机制,使用ITask<>的Handle()扩展方法捕获自定义业务Exception实现返回指定值。

Clone this wiki locally