WebApiClient的出现,大幅度减轻了接口调用者的工作量,而且在调用Http接口上还非常容易维护和更新,还可以轻松应付设计不太友好的一些Http接口
使用WebApiClient,编程人员不再需要手动实现路径拼接,参数拼接,请求体组装和响应映射为模型这些繁琐的过程.
以下为WebApiClient应用到项目中的一般流程
声明http接口的Interface 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 [JsonReturn ]public interface IlotRemotePush : IDisposable { [HttpPost("/CreateAccount" ) ] ITask<ApiResult<PushAccount>> CreateAccountAsync(lotBasicAuth auth); [HttpGet("/GetSevice?id={id}" ) ] ITask<ApiResult<MqttService>> GetPushServiceAsync(string id); }public interface IApiResult { ErrorCode Code { get ; set ; } string Msg { get ; set ; } }public class ApiResult <T > : IApiReult { public ErrorCode Code { get ; set ; } public string Msg { get ; set ; } public T Data { get ; set ; } }
调用http接口 WebApiClient不需要开发者实现接口,使用HttpApiClient.Create方法可以动态创建接口的实现类的实例,调用实例的方法,就完成一个Api的请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 using (var iotApi = HttpApiClient.Create<IlotRemotePush>()) { var auth = new lotBasicAuth(config.AppId, config.AppToken); var createResult = await iotApi.CreateAccountAsync(auth); if (createResult.Code != ErrorCode.NoError) { return null ; } config.PushId = createResult.Data.Id; config.PushToken = createResult.Data.Token; await db.SaveChangesAsync(); return config; }
异常定义与异常处理 在以上接口中,接口返回的都是ApiResult
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class lotException : Exception { public ErrorCode ErrorCode{ get ; private set ; } public lotException (IApiResult apiResult ) : base (apiResult.Msg ) { this .ErrorCode = apiResult.Code; } }
还应该在Interface上扩展JsonResult,用于将ApiResult的ErrorCode转换为lotExcetion,并抛出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class lotJsonResultAttribute : JsonReturnAttribute { protected override async Task<object > GetTaskResult (ApiActionContext context ) { var apiResult = await base .GetTaskResult(context) as IApiResult; if (apiResult != null && apiResult.Code != ErrorCode.NoError) { throw new lotException(apiResult); } return apiResult; } }
然后将新的lotJsonResultAttribute在Interface上替换JsonReturnAttribute
1 2 3 4 [lotJsonResult ]public interface IlotRemotePush : IDisposable { ... }
最后,调用http接口的时候,可以使用Handle()扩展方法处理异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 using (var iotApi = HttpApiClient.Create<IlotRemotePush>()) { var auth = new lotBasicAuth(config.AppId, config.AppToken); var createResult = await iotApi.CreateAccountAsync(auth).Handle() .WhenCatch<lotException>(ex => { return default (ApiResult<PushAccount>); }) .WhenCatch<lotException>(ex => { return default (ApiResult<PushAccount>); }); if (createResult == null ) { return null ; } config.PushId = createResult.Data.Id; config.PushToken = createResult.Data.Token; await db.SaveChangesAsync(); return config; }