前言

本篇文章的内容是WebApiClient应用说明篇,如果你没有了解过WebApiClient,可以先阅读以下相关文章:

背景

随着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类型,此类型定义了一个ErrorCode类型的Code字段,这是业务的错误码,我们可以把它转换为.net的异常来处理。

/// <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开源作出自己的一点贡献。

使用WebApiClient请求和管理Restful Api的更多相关文章

  1. Django后端项目----RESTful API

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...

  2. RESTful API 学习【第1篇】

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...

  3. 细说RESTful API之文档管理

    目录 API文档格式 文档管理方式 基于注解实现,代码和文档在一起 Swagger Api2Doc 基于API测试工具生成 Postman rest-client 独立编写文档 RAP DOCleve ...

  4. Django编写RESTful API(二):请求和响应

    欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...

  5. HTTP请求封装:Ajax与RESTful API

    一.HTTP请求 HTTP即超文本传输协议,用以进行HTML 文件. 图片文件. 查询结果等的网络传输. 一个完整的HTTP请求包括:请求行.请求头.空行和请求数据(请求数据可以为空) HTTP1.1 ...

  6. 请求与上传文件,Session简介,Restful API,Nodemon

    作者 | Jeskson 来源 | 达达前端小酒馆 请求与上传文件 GET请求和POST请求 const express = require('express'); const app = expre ...

  7. httpclient连接池在ES Restful API请求中的应用

    package com.wm.utils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http ...

  8. 使用Flask设计带认证token的RESTful API接口[翻译]

    上一篇文章, 使用python的Flask实现一个RESTful API服务器端  简单地演示了Flask实的现的api服务器,里面提到了因为无状态的原则,没有session cookies,如果访问 ...

  9. RESTful API 设计最佳实践

    背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...

随机推荐

  1. BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2152  Solved: 716[Submit][Status] ...

  2. 剑指offer得意之作——顺时针打印矩阵

    题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3 ...

  3. ansible 检查大量客户端的文件与配置情况

    ansible pro_adservers -m command -a 'w' ansible pro_adservers -m command -a 'hostname' ansible pro_a ...

  4. iOS 开发之 Xcode installation failed invalid argument!

    1.运行模拟器的时候 报出:installation failed invalid argument! 原因分析:我把Bundle indentifier 置为空了! http://stackover ...

  5. 关于Frame加背景的那点事?

    最近新生问我一个问题,继承自Frame(可不是继承自JFrame)的框架怎样添加背景图片, 真够坑的,当时还真懵了,废话少说直接上代码: import java.awt.*; import java. ...

  6. C++11 标准库也有坑(time-chrono)

    恰巧今天调试程序遇到时间戳问题, 于是又搜了搜关于取时间戳,以及时间戳转字符串的问题, 因为 time()   只能取到秒(win和linux) 想试试看能不能找到 至少可以取到毫秒的, 于是, 就找 ...

  7. 【Unity3D技术文档翻译】第1.7篇 AssetBundles 补丁更新

    上一章:[Unity3D技术文档翻译]第1.6篇 使用 AssetBundle Manager 本章原文所在章节:[Unity Manual]→[Working in Unity]→[Advanced ...

  8. R学习笔记:了解R的使用

    R是一种区分大小写的解释性语言,只支持单行注释,注释由符号#开头,当前行出现在#之后的任何文本都会被R解释器忽略.R脚本的一次执行叫做一个会话(Session),可以通过函数quit()退出当前的会话 ...

  9. Python 练习册,每天一个小程序----第0000题

    题目 第 0000 题: 将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果. 类似于图中效果 Code: from PIL import Image,Imag ...

  10. WC2016自测

    挑战NPC 原题链接 爆搜20分,贪心10分,网络流30分 //挑战NPC #include <cstdio> #include <cstring> #include < ...