在线咨询
QQ咨询
服务热线
服务热线:13125520620
TOP

使用WebApiClient请求和管理Restful Api

发布时间:2018-3-8 浏览:3026

 
背景
 
随着Wcf、Webservice等的SOAP的份额越来越少,以及Restful Api的兴起,目前几乎所有新平台提供的接口,都只提供Restful Api,而.net平台下,没有类似Wcf这么简单的客户端可以直接请求和管理这些Restful api的解决方案,.net平台提供的HttpWebRequest、WebClient和HttpClient这三个类库,可用于实现Http接口的请求,但相比wcf得益于soap自我描述实现的自动生成客户端调用代码,Restful就没这么方便了,无论使用HttpWebRequest还是HttpClient,都需要对每个Api缩写沉长的调用代码。
 
使用WebApiClient
 
WebApiClient是在这样的背景下产生一款Http全异步的客户端库,它的出现,大幅度减轻了接口调用者的工作量,而且在调用Http接口上还非常容易维护和更新,还可以轻松应对设计不太友好的一些http接口。
 
使用WebApiClient,编程人员不再需要手动实现路径拼接、参数拼接、请求体组装和响应映射为模型这些繁琐的过程,以下为WebApiClient应用到项目中的一般流程:
 
1 声明http接口的Interface
 
[JsonReturn]
public interface IIotRemotePush : IDisposable
{
    /// <summary>
    /// 创建远程推送账号
    /// </summary>
    /// <param name="auth">授权</param>
    /// <returns></returns>
    [HttpPost("/v1/RemotePush/CreateAccount")]
    ITask<ApiResult<PushAccount>> CreateAccountAsync(IotBasicAuth auth);
 
    /// <summary>
    /// 获取推送服务信息
    /// </summary>
    /// <param name="id">pushId</param>
    /// <returns></returns>
    [HttpGet("/v1/Mqtt/GetPushSevice?id={id}")]
    ITask<ApiResult<MqttService>> GetPushSeviceAsync(string id);
}
 
/// <summary>
/// Api结果接口
/// </summary>
public interface IApiResult
{
    /// <summary>
    /// 错误码
    /// </summary>      
    ErrorCode Code { get; set; }
 
    /// <summary>
    /// 相关提示信息
    /// </summary>
    string Msg { get; set; }
}
 
 
/// <summary>
/// 表示Api结果
/// </summary>
public class ApiResult<T> : IApiResult
{
    /// <summary>
    /// 错误码
    /// </summary>
    public ErrorCode Code { get; set; }
 
    /// <summary>
    /// 相关提示信息
    /// </summary>
    public string Msg { get; set; }
 
    /// <summary>
    /// 业务数据
    /// </summary>
    public T Data { get; set; }
}
2 调用http接口
 
WebApiClient不需要开者实现接口,使用HttpApiClient.Create方法可以动态创建接口的实现类的实例,调用实例的方法,就完成一个Api的请求。
 
using (var iotApi = HttpApiClient.Create<IIotRemotePush>())
{
    var auth = new IotBasicAuth(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;
}
3 异常定义与异常处理
 
在以上接口中,接口返回的都是ApiResult
 
/// <summary>
/// 表示Iot异常
/// </summary>
public class IotException : Exception
{
    /// <summary>
    /// 错误码
    /// </summary>
    public ErrorCode ErrorCode { get; private set; }
 
    /// <summary>
    /// Iot异常
    /// </summary>
    /// <param name="apiResult">api结果值</param>
    public IotException(IApiResult apiResult)
        : base(apiResult.Msg)
    {
        this.ErrorCode = apiResult.Code;
    }
}
我们还应该在Interface上扩展JsonResult,用于将ApiResult的ErrorCode转换为IotException,并抛出:
 
/// <summary>
/// 表示IotJson结果
/// </summary>
public class IotJsonResultAttribute : 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 IotException(apiResult);
        }
        return apiResult;
    }
}
然后将新的IotJsonResultAttribute在Interface上替换JsonReturnAttribute:
 
[IotJsonResult]
public interface IIotRemotePush : IDisposable
{
   ...
}
最后,调用http接口的时候,可以使用Handle()扩展方法处理异常:
 
using (var iotApi = HttpApiClient.Create<IIotRemotePush>())
{
    var auth = new IotBasicAuth(config.AppId, config.AppToken);
    var createResult = await iotApi.CreateAccountAsync(auth)
        .Handle()
        .WhenCatch<IotException>(ex =>
        {
            // process exception
            return default(ApiResult<PushAccount>);
        })
        .WhenCatch<Exception>(ex =>
        {
            // process exception
            return default(ApiResult<PushAccount>);
        });
 
    if (createResult == null)
    {
        return null;
    }
 
    config.PushId = createResult.Data.Id;
    config.PushToken = createResult.Data.Token;
    await db.SaveChangesAsync();
 
    return config;
}
WebApiClient现状
 
WebApiClient项目目前已加入.NET China Foundation,正在为.net开源作出自己的一点贡献。
 

TAG
软件定制,软件开发,瀚森HANSEN
0
该内容对我有帮助