WebAPI学习
WebAPI概述
今天的web计算平台包含了广泛的功能,其中的大部分均可以通过API(应用程序编程接口)访问。
web平台归为6个基本设施,都会用到webapi,包括存储服务、消息服务、计算服务、信息服务、搜索服务、Web2.0服务。
定义:
API是拥有一组函数组成的某种接口,它允许程序员访问应用程序的特定的功能或数据,操作系统或其他服务。
Web API顾名思义,是一个可以使用HTTP协议访问的API。这是一个概念,而不是技术。
我们可以使用不同的技术来构建Web API,如Java、.net等。
ASP.NET Web API是用于构建可以从任何客户机访问(包括浏览器和移动设备)的HTTP服务的框架。 它是一种基于.NET Framework构建RESTful应用程序的理想平台。
Asp.Net Web API是一个可扩展的框架,用于构建基于HTTP的服务,这种服务可以在不同平台上的不同应用程序中访问:例如web应用、窗体应用、移动应用等等。
它和ASP.NET MVC有相同的工作方式,但Web Api应用程序接收到请求后返回数据,而不是像MVC返回html视图。
它就像一个webservice 或WCF服务,但例外在于它只支持HTTP协议。
RESTful架构
REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文中提到:"我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条件和原则。" 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。
ASP.NET Web API VS WCF
web api |
wcf |
开源,支持.net framework |
支持.net framework |
只支持HTT通信协议 |
支持HTTP,TCP,UDP以及自定义通信协议等 |
良好的路由机制来匹配url与对应接口 |
基于Attribute来匹配 |
使用类似于Asp.net MVC的路由规则和Controller模型 |
使用Service,契约等 |
不支持可靠的消息传递和事务。 |
支持可靠的消息传递和事务。 |
可以使用HttpConfiguration 来配置Web Api,不一定需要web.config配置 |
使用web.config和Attribute来配置一个服务 |
适合构建RESTful服务。 |
支持构建RESTful服务但有局限性 |
什么时候用WCF
- 如果你使用的是.net framework3.5,可以选择使用wcf,因为Web Api不支持.net 3.5及更低的版本。
- 如果你需要支持多种协议如HTTP、TCP、命名管道等,可以选择WCF服务。
- 如果你想建立满足WS - *标准的可靠的消息传递、交易、信息安全方面的服务,可以选择WCF服务。
- 如果您想要使用请求-应答,单向或者双向消息通信模式,可以选择WCF。
什么时候用Web API
- 如果您使用的是.Net Framework4.0或以上版本,可以选择Web API。
- 如果你想建立一个仅支持HTTP协议的服务,可以选择Web API。
- 如果你想构建基于restful的HTTP服务,可以选择Web API。
- 如果你已经很了解Asp.Net MVC,可以选择Web API。
Web API Controller
Web API控制器类似于ASP.NET MVC控制器。它用来处理传入的HTTP请求并将响应发送回调用者。
Web API控制器是一个类,你可以在控制器文件夹中创建,也可以在您的项目的根文件夹下的任何其他文件夹中创建。
一个控制器类的名字必须以“Controller”结束,它必须继承自System.Web.Http.ApiController类。控制器的所有公共方法(public)被称为操作方法。
根据传入的请求URL和HTTP动词(GET/POST/PUT/PATCH/DELETE),Web API决定执行哪个Web API控制器和操作方法,如Get()方法将处理HTTP GET请求,POST()方法将处理HTTP POST请求,Put()方法将处理HTTP PUT请求,DELETE()方法将为上述Web API处理HTTP DELETE请求。
如果你想写一些不用HTTP动词命名的方法,可以给方法添加一些适当的HTTP动词属性,如[HttpGet] [HttpPost] [HttpPut] 等等就像MVC控制器一样。
特点
- 它必须继承自System.Web.Http.ApiController类。
- 它可以在项目的根文件夹中的任何文件夹中创建。但是,按照约定建议在控制器文件夹中创建控制器类。
- 动作方法名可以与HTTP动词名相同,也可以以HTTP动词开头,或将HTTP动词属性添加到方法上。
- 一个动作方法的返回类型可以是任何基本或复杂类型。
要允许多个HTTP方法进行操作,或者允许GET,PUT,POST和DELETE以外的HTTP方法,请使用AcceptVerbs属性,该属性采用HTTP方法列表。
[AcceptVerbs("GET", "HEAD")]
public Product FindProduct(id)
Web API控制器与MVC控制器的区别
Web API 控制器 |
MVC 控制器 |
继承自System.Web.Http.ApiController类 |
继承自System.Web.Mvc.Controller |
方法名称必须以Http动词开头或者添加Http属性 |
必须添加Http属性 |
返回请求对应的数据 |
返回视图 |
返回xml格式或json格式数据,也可以返回自定义的格式的数据 |
返回ActionResult 或者其他类型的数据 |
支持.net4.0及以上版本 |
支持.net3.5及以上版本 |
配置Web API
Web API支持基于代码的配置。它不能被配置在Web.config文件中。
我们可以配置Web API来定制Web API托管基础设施和组件的行为如路由、格式器,过滤器,DependencyResolver,messagehandler ParamterBindingRules、属性、服务等。
Web API应用程序启动时,配置处理器随之启动(Global.asax)它将通过调用Application_Start方法来调用GlobalConfiguration.Configure(WebApiConfig.Register)方法。
Configure()方法需要传入回调方法,该回调方法就是配置Web API的代码。在默认情况下这个回调方法是静态WebApiConfig.Register()方法。
WebApiConfig.Register()方法包含一个类型为 HttpConfiguration的参数,该参数用于用于配置Web API。
HttpConfiguration类包括以下属性,通过它您可以覆盖默认的Web API的行为。
属性 |
描述 |
DependencyResolver |
获取或者设置依赖的属性 |
Filters |
获取或设置过滤器 |
Formatters |
获取或设置formatters |
IncludeErrorDetailPolicy |
获取或者设置异常信息是否该包含在error messages中 |
MessageHandlers |
获取或设置Message handlers |
ParameterBindingRules |
获取或设置参数绑定规则 |
Properties |
获取或设置当前web api实例的properties |
Routes |
获取或设置路由规则 |
Services |
获取或设置services |
Web API路由
WebApiConfig类可以配置Web API
将HTTP请求路由到控制器(控制器是处理HTTP请求的类。)。
Web API路由类似于ASP.NET MVC路由。它传入HTTP请求路由到在Web API控制器的一个特定的操作方法。
主要区别在于Web API使用HTTP方法而不是URI路径来选择操作。您也可以在Web API中使用MVC风格的路由。
Web API支持两种类型的路由:
- 基于约定的路由
- 基于属性的路由
基于约定的路由
在基于约定的路由中,Web API使用模板来确定该请求由哪个路由控制器和操作方法执行。至少有一个路由模板必须添加到路由表,以处理各种HTTP请求。
/// <summary>
/// 路由配置等
/// </summary>
/// <param name="config"></param>
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务 // 使Web API 支持 属性路由
config.MapHttpAttributeRoutes(); //Web API 的 HTTP路由(默认)
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
config.Routes是一个路由表或HttpRouteCollection类型的集合。
“DefaultApi”路由被MapHttpRoute()扩展方法添加到路由表中。您可以创建一个新的路由并手动添加到集合,如下所示。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes(); // define route
IHttpRoute defaultRoute = config.Routes.CreateRoute("api/{controller}/{id}", new { id = RouteParameter.Optional }, null); // Add route
config.Routes.Add("DefaultApi", defaultRoute);
}
}
在路由中使用“api”的原因是为了避免与ASP.NET MVC路由发生冲突。这样,您可以将“/ contacts”转到MVC控制器,“/ api / contacts”转到Web API控制器。当然,如果你不喜欢这个约定,你可以改变默认的路由表。
配置多个路由
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes(); // school route
config.Routes.MapHttpRoute(
name: "School",
routeTemplate: "api/myschool/{id}",
defaults: new { controller="school", id = RouteParameter.Optional }
constraints: new { id ="/d+" }
);
// default route
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
School路由配置在DefaultApi路由之前。所以任何传入请求首先会与School路线匹配,如果传入的请求url不匹配则才会与DefaultApi路由匹配。
基于属性的路由
Web API 2开始支持Attribute路由。事实上,您可以在同一个项目中结合使用这两种路由技术。
顾名思义,Attribute路由使用[Route()]属性来定义路由。Attribute路由可以应用在任何控制器或操作方法上。
基于约定的路由的缺点
不幸的是,基于约定的路由很难支持RESTful API中常见的某些URI模式。例如,资源通常包含子资源:客户有订单,电影有演员,书有作者等等。创建反映这些关系的URI是很自然的:
/customers/1/orders
您只需将一个属性添加到控制器操作中:
[Route("customers/{customerId}/orders")] public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }
API版本控制
在这个例子中,“/ api / v1 / products”会被路由到与“/ api / v2 / products”不同的控制器。
多种参数类型
在本例中,“1”是订单号,但“2013/06/16”指定日期。
/orders/1
/orders/2013/06/16
启用属性路由
为了在Web API中使用Attribute路由,它必须通过调用config.MapHttpAttributeRoutes()方法启用WebApiConfig。
路由约束
1、假如一个url,同时控制器有两个方法满足,会发生什么?
[Route("api/{StrNum}/students")]
[Route("api/{intNum}/students")]
//这样提供api接口是不对的。不能提供一样的接口。编译能通过,但是请求会报错 {"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were found that match the request:
解决方案:
通过路由约束,可以限制路由模板中参数的匹配方式。一般语法是“{参数:约束}”。例如:
[Route("users/{id:int}"]
public User GetUserById(int id) { ... } [Route("users/{name}"]
public User GetUserByName(string name) { ... }
在这里,只有当URI的“id”段是一个整数时才会选择第一条路由。否则,将选择第二条路线。
参数绑定
Web API如何将HTTP请求数据绑定到一个操作方法的参数中。
操作方法在Web API控制器中可以有一个或多个不同类型的参数。它可以是原始类型或复杂类型。
Web API根据URL的查询字符串或请求主体中参数类型来绑定操作方法的参数。
默认情况下,如果参数类型为原始类型,如int, bool, double, string, GUID, DateTime, decimal或任何其他可以从字符串类型转换的类型,将会从query string中获取。
如果参数类型是复杂类型,Web API默认将试图从请求主体获取值。
HTTP方法 |
Query string |
Request Body |
Get |
简单类型、复杂类型 |
无 |
Post |
简单类型 |
复杂类型 |
1、Get基本参数类型(可以多个参数)
public Student Get(int id, string name)
注意:查询字符串参数名称和操作方法参数名称必须相同(不区分大小写)。名称不匹配的参数将不会赋值,参数的先后顺序没有要求。
以下是上述操作方法有效的HTTP GET请求。
http://localhost/api/student?id=1&name=steve
http://localhost/api/student?ID=1&NAME=steve
http://localhost/api/student?name=steve&id=1
2、POST基本类型参数
使用HTTP POST请求来创建新的资源。他可以将请求数据放在Request Body中,也可以放在Query String中。
例如,如果一个HTTP POST请求是http://localhost/api/student?id=1&name=steve,那么id的值为1,name的值为steve。
3、POST复杂类型参数
Post操作方法可以包括基本类型和复杂类型参数。参考下面的例子。
public class Student
{
public int Id { get; set; }
public string Name { get; set; } }
public class StudentController : ApiController
{
public Student Post(int age, Student student)
{
}
}
默认情况下,Web API将从query string中获取id的值,从request body中获取student的值【Web API将从请求体中提取JSON对象并自动将它转换成Student对象,因为JSON对象属性的名称与Student类属性的名称匹配(不区分大小写)。】。
注意:Post操作方法不能包含多个复杂类型的参数,因为最多允许一个参数读取请求主体中的数据。
4、FromURI与FromBody
默认情况下,Web API从查询字符串中得到基本类型参数的值,从请求主体中得到复杂类型参数的值。但是,如果我们想改变这种默认行为呢?
可以使用[FromUri]属性,使Web API来从查询字符串中获取复杂类型的值,
使用(FromBody)属性可以使Web API从请求主体获取原始类型的值。注意:FromBody属性只能应用于一个Action方法的一个基本参数。
注意:复杂类型属性和查询字符串参数的名称必须匹配。
同样,参考以下Post方法的例子。
public class StudentController : ApiController
{
public Student Post([FromUri]Student stud)
{
}
}
现在,Web API将从查询字符串中提取Student参数的属性的值,而不是请求主体。
5、总结:
Action方法返回类型
操作方法的返回类型,返回数据是Web API对请求作出响应并发送到客户端的数据。
Web API操作方法后主要有以下几种返回类型:
- Void类型。例如 删除数据,返回void,相应204(“No Content”)
- 简单类型或复杂类型
- HttpResponseMessage类型。优点是,您可以自己配置一个响应。你可以按照您的需求设置状态代码,内容或错误消息(如果有的话)。
- IHttpActionResult类型
WebAPI学习的更多相关文章
- Asp.Net Core WebApi学习笔记(四)-- Middleware
Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...
- 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换
路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...
- WebAPI学习点滴(二)
刚开始学习WebApi就遇到了问题,在同一个API控制器中,如果两个方法的签名相同,比如 [HttpGet] public string GetString() { return "Hell ...
- WebAPI学习日记一:Ajax请求传递参数遇到的问题
首先,本人大学刚毕业,想把自己学习的一些东西记录下来,也是和大家分享,如有不对之处还请多加指正.声明:但凡是我博客里的文章均是本人实际操作遇到的例子,不会随便从网上拷贝或者转载,本着对自己和观众负责的 ...
- WebAPI学习及Swagger使用
本文用来保存自己学习WebAPI和Swagger使用过程中参考的文章,以及对WebAPI的初步了解. 1.RESTful风格 WebAPI只支持Http协议: 1.1.WebAPI与MVC的区别 Va ...
- ASP.NET WebApi 学习与实践系列(1)---如何创建 WebApi
写在前面 最近在做一个app的时候发现需要写后台服务.所以,在考虑是使用webapi还是使用webserver来写这个后台服务的时候.爱纠结的我,最后还是选择了使用webapi来写这个后台服务. 原因 ...
- 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(九)-- 单元测试
本篇将结合这个系列的例子的基础上演示在Asp.Net Core里如何使用XUnit结合Moq进行单元测试,同时对整个项目进行集成测试. 第一部分.XUnit 修改 Project.json 文件内容, ...
- WebApi学习总结系列第二篇(webapi的调试)
目前使用webapi的调试主要有 1.用接口宿主调试.(宿主形式多样:web.winform.还有就是直接用app进行接口调试) 2.用Fiddler抓Http信息,进行调试. 1.用接口宿主调试. ...
- WebApi学习总结系列第五篇(消息处理管道)
引言: ASP.NET WebAPI的核心框架是一个消息处理管道,这个管道是一组HttpMessageHandler的有序组合.这是一个双工管道,请求消息从一端流入并依次经过所有HttpMessage ...
- WebApi学习总结系列第四篇(路由系统)
由于工作的原因,断断续续终于看完了<ASP.NET Web API 2 框架揭秘>第二章关于WebApi的路由系统的知识. 路由系统是请求消息进入Asp.net WebApi的第一道屏障, ...
随机推荐
- MySQL直方图
MySQL8.0开始支持索引之外的数据分布统计信息可选项 我们知道,在DB中,优化器负责将SQL转换为很多个不同的执行计划,完了从中选择一个最优的来实际执行.但是有时候优化器选择的最终计划有可能随着D ...
- Android--TextView第一个单词大写
自定义TextView: public class FirstBoldTextView extends TextView { private boolean firstWordBold = false ...
- Lucene BooleanQuery中的Occur.MUST与Occur.Should
https://www.cnblogs.com/weipeng/archive/2012/04/18/2455079.html 1. 多个MUST的组合不必多说,就是交集 2. MUST和SH ...
- 安装Ubuntu18.04系统
一.安装Ubuntu系统 进入系统安装的第一个界面,开始系统的安装操作.每一步的操作,左下角都会提示操作方式!! 1.选择系统语言-English 2.键盘设置-English 3.选择操作Insta ...
- 和我一起,重零开始学习Ant Design Pro开发解决方案(二)部署示例项目
- 【洛谷 P2444】 [POI2000]病毒(AC自动机)
题目链接 这么多字符串,肯定是自动机啦. 先建出AC自动机,然后怎么表示一个安全代码没有病毒代码呢? 就是存在一条路径不经过有病毒代码段结尾的节点呗. 所以呢?有环啊!dfs一下救星了. #inclu ...
- JavaScript的书写格式及书写的注意点
JavaScript书写格式: 1.行内样式: 写在标签内部 2.内嵌样式(内联样式) : 写在一对head标签中 3.外链样式: 写在一个单独的.js文件中, 再导入进来 JavaScript书写格 ...
- mac环境下Android 反编译
连接地址: https://www.jianshu.com/p/3a305f32c4a3
- C语言的三套标准 C89(C90)、C99、C11
C语言最初由 Dennis Ritchie 于 1969 年到 1973 年在 AT&T 贝尔实验室里开发出来,主要用于重新实现 Unix 操作系统.此时,C语言又被称为 K&R C. ...
- 使用ranger替代资源浏览器
使用方法参考,这个是比较高校的: http://www.mikewootc.com/wiki/linux/usage/ranger_file_manager.html