在我前一篇博客《WebAPI前置知识:HTTP与RestfulAPI》中已经给各位简单介绍了HTTP协议与RestFul API的关系,以及一些基本的HTTP协议知识,在这些知识的铺垫下,今天,我们一起来讨论一下WEB API的适用场景,然后写我们第一个WEB API接口,并演示如何对其进行简单调用。

很多人都很迷惑,既然有了WCF为什么还要有WEB API?WEB API会不会取代WCF?

就我的看法,WCF提供的是一种RPC实现的集合,WCF的设计更多地考虑了SOA的场景,以及各种RPC的问题。很多人也会说,RestFul API也是一种RPC啊,并且WCF中也有关于RestFul 的实现啊。很多资料中RPC和RestFul在风格概念上是有一些区别的,其实我觉得这两者的区别比较主观,过度纠结这些就学院派了;我主要关注了实际使用上的一些问题,在WCF中,支持的协议很多,WS-*系列协议,以及一些更简洁的协议,其中提供了一些专用通信协议的性能是非常高的,并且WCF还提供了服务发现等功能,我认为WCF更适合内部系统间的高性能调用,社区中也有其他一些RPC方案可以选择,例如gRPC,Avor,thrift都是和WCF定位相同的产品;而WEB API是关注于HTTP RestFul风格的产品,在此基础上,任何语言、任何终端都能非常容易地进行对接,并且能利用非常成熟的各种HTTP基础设施和解决方案来进行开发、调试、负载均衡、内容分发。所以,WEB API是一种针对HTTP的,偏重于快速开发RestFul风格开放式API的开发框架。目前看来,他并不能取代WCF,他们各有适合的场景,不能认为WEB API是WCF的替代产品。

OK,现在我们来开发第一组WEB API接口!使用VS2012以后的版本都有现成的WEB API创建模板,大家跟着创建就好了,创建出来后,项目中会有MVC、WEB API的项目,WEB API对MVC有依赖,不能单独创建!而WEB API和MVC都是利用类似的路由机制,所以在默认路由中,WEB API 使用

/api/{controller}/{id} 

作为路由,添加了/api/节以区分MVC和web api。

接下来,我们添加一个WEB API的Controller,取名为PersonController,他继承于ApiController;在创建这个Controller的时候,我们就定义了一种资源:Person,在PersonController里的所有操作均围绕着Person这个资源来的。接下来我们开始定义一组增删改查操作。

在Web API中,默认路由采用了一种约定:根据谓词来进行路由,而方法名的前缀就是调用该方法对应使用的HTTP谓词。代码示例如下:

/// <summary>/// Person 为资源,对Person进行的一组操作/// </summary>public class PersonController : ApiController    {                 private static List<Person> _personLst = new List<Person>();              /// <summary>/// 获取一个Person        /// </summary>/// <param name="id">Person的ID</param>/// <returns>Person</returns>public Person GetPerson(long id)        {             return _personLst.Find(x => x.Id == id);        }        /// <summary>/// 添加一个Person        /// </summary>/// <param name="person">Person</param>public void PostAddPerson(Person person)        {            _personLst.Add(person);        }        /// <summary>/// 修改一个         /// </summary>/// <param name="id">Person Id</param>/// <param name="person">新</param>public void PutModifyPerson(long id, Person person)        {              var p = _personLst.Find(x => x.Id == id);            p.Age = person.Age;            p.Name = person.Name;            p.Sex = person.Sex;        }        /// <summary>/// 删除一个Person         /// </summary>/// <param name="id">Person ID</param>public void DeletePerson(long id)        {            _personLst.RemoveAll(x => x.Id == id);        } }

一个简单的针对资源的CRUD操作的API就好了,不用解析输入,不用拼接输出,就是那么简单!让我们来遛一遛!

发送请求:谓词为POST,语义创建Person,Person描述在Body里,head中声明了Body通过Json序列化。

收到响应:响应码204,属于2XX类型执行成功,Body里没有数据

发送请求:谓词为GET,语义为查询Person资源,Id为1的,head中声明希望接收使用XML序列化的数据

收到响应:响应码为200,执行成功,Body中有数据,数据使用XML序列化

发送请求:谓词为PUT,语义为修改ID为1的Person资源,修改内容在Body中,Content-Type标明Body使用Json序列化,在Body中我们将Name修改为Test1Changed

收到响应,响应码为204,执行成功

发送请求:谓词为GET,语义为查询ID为1的Person资源,Accept标明希望接收到Json数据

收到响应:可以看到Body为使用Json序列化的内容,Name属性已经变更为Test1Changed

发送请求:谓词为DELETE,语义为删除ID为1的Person资源

收到响应:响应码204,执行成功

发送请求:谓词为GET,语义为查询ID为1的Person资源,Accept标明希望接收到Json数据

收到响应:响应码为200,执行成功,响应内容为null,资源已删除

这就是我用Fiddler来发送、调用的一组RestFul接口,大家可以看到,整个调用过程使用到了HTTP的语义,用到了谓词路由、内容协商。在增、删、改操作中,我都是使用void作为返回值,根据HTTP Code 判断,大家也可以自定义一些返回数据来做出更进一步的操作描述。

在写了这些API后,我们需要在程序中调用,我以C#为例写一组对这些接口调用的实现。在C#中,传统调用HTTP接口一般有两种办法: WebRequest/WebResponse组合的方法调用和WebClient类进行调用。第一种方法抽象程度较低,使用较为繁琐;而WebClient主要面向了WEB网页场景,在模拟Web操作时使用较为方便,但用在RestFul场景下却比较麻烦,在Web API发布的同时,.NET提供了两个程序集:System.Net.Http和System.Net.Http.Formatting。这两个程序集中最核心的类是HttpClient。在.NET4.5中带有这两个程序集,而.NET4需要到Nuget里下载Microsoft.Net.Http和Microsoft.AspNet.WebApi.Client这两个包才能使用这个类,更低的.NET版本就只能表示遗憾了只能用WebRequest/WebResponse或者WebClient来调用这些API了。

在使用中,System.Net.Http这个程序集提供了HttpClient类以及相关的HTTP调用,而System.Net.Http.Formatting提供了一些针对HttpClient的帮助扩展,更好地支持了内容协商、Content创建等功能。下面我就和大家一起写一下这个例子:

我们新建一个控制台程序:

代码如下:

public class Person    {                public long Id { get; set; }   

        public string Name { get; set; }        public int Age { get; set; }        public string Sex { get; set; }        public override string ToString()        {                          return $"Id={Id} Name={Name} Age={Age} Sex={Sex}";        }    }    class Program    {               static void Main(string[] args)        {                 var client = new HttpClient();            client.BaseAddress = new Uri("http://localhost:22658/"); //基本的API URL            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //默认希望响应使用Json序列化            Run(client);            Console.ReadLine();        }        static async void Run(HttpClient client)        {                      var result = await AddPerson(client);            Console.WriteLine($"添加结果:{result}"); //添加结果:truevar person = await GetPerson(client);            Console.WriteLine($"查询结果:{person}"); //查询结果:Id=1 Name=test Age=10 Sex=F            result = await PutPerson(client);            Console.WriteLine($"更新结果:{result}"); //更新结果:true            result = await DeletePerson(client);            Console.WriteLine($"删除结果:{result}"); //删除结果:true        }        static async Task<bool> AddPerson(HttpClient client)        {            return await client.PostAsJsonAsync("api/Person", new Person() { Age = 10, Id = 1, Name = "test", Sex = "F" }) //向Person发送POST请求,Body使用Json进行序列化                                     .ContinueWith(x => x.Result.IsSuccessStatusCode);  //返回请求是否执行成功,即HTTP Code是否为2XX        }        static async Task<Person> GetPerson(HttpClient client)        {                       return await await client.GetAsync("api/Person/1") //向Person发送GET请求                .ContinueWith(x => x.Result.Content.ReadAsAsync<Person>(                              //获取返回Body,并根据返回的Content-Type自动匹配格式化器反序列化Bodynew List<MediaTypeFormatter>() {new JsonMediaTypeFormatter()/*这是Json的格式化器*/                                                    ,new XmlMediaTypeFormatter()/*这是XML的格式化器*/}));        }        static async Task<bool> PutPerson(HttpClient client)        {            return await client.PutAsJsonAsync("api/Person/1", new Person() { Age = 10, Id = 1, Name = "test1Change", Sex = "F" }) //向Person发送PUT请求,Body使用Json进行序列化                                    .ContinueWith(x => x.Result.IsSuccessStatusCode);  //返回请求是否执行成功,即HTTP Code是否为2XX        }        static async Task<bool> DeletePerson(HttpClient client)        {            return await client.DeleteAsync("api/Person/1") //向Person发送DELETE请求                .ContinueWith(x => x.Result.IsSuccessStatusCode); //返回请求是否执行成功,即HTTP Code是否为2XX        } }

这就完成了这组API的调用,是不是非常简单方便?HTTPClient使用全异步的方法,并且他有良好的扩展性,我会在之后的博客中再聊这个问题。

OK,到此为止一组简单的Restful API和C#的调用客户端就完成了,但这只是开始,Web API是一个很强大的框架,他的扩展点非常丰富,这些扩展能为我们的开发提供很多的帮助,下一篇博文我将为大家带来WEB API中Filter的使用。

博文中如有不正确的地方欢迎大家指正。

原文地址:http://www.cnblogs.com/UliiAn/p/5373854.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

WEB API系列(一):WEB API的适用场景、第一个实例相关推荐

  1. maven mybatis mysql_Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问...

    标签: 本篇内容还是建立在上一篇Java Web学习系列--Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Ja ...

  2. java date加一天_Java日期时间API系列15-----Jdk8中API类,java日期计算2,年月日时分秒的加减等...

    通过Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析 ,可以看出java8设计非常好,实现接口Temporal, Tempora ...

  3. 适合0基础的web开发系列教程-web 存储

    HTML5 web 存储,一个比cookie更好的本地存储方式. 什么是 HTML5 Web 存储? 使用HTML5可以在本地存储用户的浏览数据. 早些时候,本地存储使用的是 cookie.但是Web ...

  4. [Web Chart系列之一]Web端图形绘制SVG,VML, HTML5 Canvas 技术比较

    先介绍一下矢量图的概念: 矢量图使用直线和曲线来描述图形,这些图形的元素是一些点.线.矩形.多边形.圆和弧线等等,它们都是通过数学公式计算获得的.例如一幅花的矢量图形实际上是由线段形成外框轮廓,由外框 ...

  5. [Web Chart系列之一(续)]Web端图形绘制SVG,VML, HTML5 Canvas 简单实例

    前言 本篇是继 [Web Chart系列之一]Web端图形绘制SVG,VML, HTML5 Canvas 技术比较 的补充和实例说明各种技术的使用方式. VML 的用法和实例 引入命名空间之后,就可以 ...

  6. 玩 High API 系列好文(一):智能客服、钉钉Ding功能、智能云相册、快速实现身份验证

    云栖君导读:通过本系列文章,您可以快速了解每个API提供的功能及适用的场景,帮助您快速查找到满足特定功能的API.您也可以通过对多个API进行编排组合,来轻松完成一项应用创新. 一. 玩 High A ...

  7. Web API系列(三)统一异常处理

    前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,<Web API系列(二)接口安全和参数校验>,本文主要介绍Web API异常结果的处理.作为内部或者是对外提供 ...

  8. WEB API 系列(二) Filter的使用以及执行顺序

    在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don't Repeat Yourself)思想 ...

  9. Web API系列之三 基本功能实现

    Web API系列之二讲解了如何搭建一个WebApi的基架,本文主要在其基础之上实现基本的功能.下面开始逐步操作: 一.配置WebApi的路由-用于配置外部如何访问内部资源的url的规则 1.添加Gl ...

  10. Web API系列(三):添加接口详细说明及测试

    1.引言 前边两篇博客介绍了Web API的基本框架以及路由配置,这篇博客主要解决在前后端分离项目中,为前端人员提供详细接口说明的问题,主要是通过修改WebApi HelpPage相关代码和添加Web ...

最新文章

  1. Float构建三栏DIV CSS网页布局
  2. 115.什么是SHELL
  3. nodejs 实践:express 最佳实践(六) express 自省获得所有的路由
  4. VMware 安装LINUX系统(一)
  5. w10计算机字体怎么设置在哪里设置,win10系统电脑字体设置的操作方法
  6. soapUI接口测试工具
  7. 从0开始,如何设计一个社交电商产品
  8. vue-waterfall2瀑布流使用及坑
  9. 爬取初试----猫眼电影,猫眼评分
  10. python上下对齐_python-docx设置表格对齐方式
  11. 银河麒麟服务器系统使用的一些问题和解决方案
  12. 常用计算机软件不包括什么,大学计算机基础试题及答案(二)
  13. Docker安装配置Jenkins教程
  14. js逆向,破解企名片网站的加密参数
  15. 【笨嘴拙舌WINDOWS】实践检验之按键精灵【Delphi】
  16. idea右边依赖爆红的解决方案
  17. mysql索引最左前缀原则
  18. 计算机毕业设计SSM车站商铺信息管理系统【附源码数据库】
  19. Patroni的pause和resume功能
  20. 浅绛彩瓷的行情与收藏

热门文章

  1. Linux挂载命令mount详解
  2. Cus系统beta1.2发布
  3. 测试Live Writer 发表博客
  4. 管理Apache服务器访问日志
  5. 微软翻译api的使用介绍和注意事项
  6. 算法面试:精选微软等公司经典的算法面试100题 第26-35题
  7. 让 Hangfire 使用 MongoDB 存储
  8. 听说过Netflix的Chaos Monkey吗?不用羡慕,我们.NET也有
  9. .NET Core 服务在 ARM64 服务器中的部署
  10. NET问答: 为什么时间格式 dd/MM/yyyy 转成 DateTime 会报错?