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控制器一样。

 特点

  1. 它必须继承自System.Web.Http.ApiController类。
  2. 它可以在项目的根文件夹中的任何文件夹中创建。但是,按照约定建议在控制器文件夹中创建控制器类。
  3. 动作方法名可以与HTTP动词名相同,也可以以HTTP动词开头,或将HTTP动词属性添加到方法上。
  4. 一个动作方法的返回类型可以是任何基本或复杂类型。

要允许多个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支持两种类型的路由:

  1. 基于约定的路由
  2. 基于属性的路由

基于约定的路由

在基于约定的路由中,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操作方法后主要有以下几种返回类型:

  1. Void类型。例如 删除数据,返回void,相应204(“No Content”)
  2. 简单类型或复杂类型
  3. HttpResponseMessage类型。优点是,您可以自己配置一个响应。你可以按照您的需求设置状态代码,内容或错误消息(如果有的话)。
  4. IHttpActionResult类型

WebAPI学习的更多相关文章

  1. Asp.Net Core WebApi学习笔记(四)-- Middleware

    Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...

  2. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  3. WebAPI学习点滴(二)

    刚开始学习WebApi就遇到了问题,在同一个API控制器中,如果两个方法的签名相同,比如 [HttpGet] public string GetString() { return "Hell ...

  4. WebAPI学习日记一:Ajax请求传递参数遇到的问题

    首先,本人大学刚毕业,想把自己学习的一些东西记录下来,也是和大家分享,如有不对之处还请多加指正.声明:但凡是我博客里的文章均是本人实际操作遇到的例子,不会随便从网上拷贝或者转载,本着对自己和观众负责的 ...

  5. WebAPI学习及Swagger使用

    本文用来保存自己学习WebAPI和Swagger使用过程中参考的文章,以及对WebAPI的初步了解. 1.RESTful风格 WebAPI只支持Http协议: 1.1.WebAPI与MVC的区别 Va ...

  6. ASP.NET WebApi 学习与实践系列(1)---如何创建 WebApi

    写在前面 最近在做一个app的时候发现需要写后台服务.所以,在考虑是使用webapi还是使用webserver来写这个后台服务的时候.爱纠结的我,最后还是选择了使用webapi来写这个后台服务. 原因 ...

  7. 使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(九)-- 单元测试

    本篇将结合这个系列的例子的基础上演示在Asp.Net Core里如何使用XUnit结合Moq进行单元测试,同时对整个项目进行集成测试. 第一部分.XUnit 修改 Project.json 文件内容, ...

  8. WebApi学习总结系列第二篇(webapi的调试)

    目前使用webapi的调试主要有 1.用接口宿主调试.(宿主形式多样:web.winform.还有就是直接用app进行接口调试) 2.用Fiddler抓Http信息,进行调试. 1.用接口宿主调试. ...

  9. WebApi学习总结系列第五篇(消息处理管道)

    引言: ASP.NET WebAPI的核心框架是一个消息处理管道,这个管道是一组HttpMessageHandler的有序组合.这是一个双工管道,请求消息从一端流入并依次经过所有HttpMessage ...

  10. WebApi学习总结系列第四篇(路由系统)

    由于工作的原因,断断续续终于看完了<ASP.NET Web API 2 框架揭秘>第二章关于WebApi的路由系统的知识. 路由系统是请求消息进入Asp.net WebApi的第一道屏障, ...

随机推荐

  1. Django模型层之更多操作

    Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为 ...

  2. 【转】基于FPGA的Sobel边缘检测的实现

    前面我们实现了使用PC端上位机串口发送图像数据到VGA显示,通过MATLAB处理的图像数据直接是灰度图像,后面我们在此基础上修改,从而实现,基于FPGA的动态图片的Sobel边缘检测.中值滤波.Can ...

  3. InnoDB的MVCC实现原理

    InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的. 这两个列,一个保存了行的创建时间,一个保存了行的过期时间(删除时间).当然存储的并不是实际时间,而是系统版本号(sytem ve ...

  4. LOJ6587 WF2019 交通堵塞 CRT、bitset

    传送门 首先设\(P = lcm(r_i + g_i)\),因为\(P \mid 2019!\),所以在\([0,2019!]\)里随机实数相当于在\([0,2019!)\)随机实数,相当于在\([0 ...

  5. Linux虚拟机设置静态ip

    二.设置静态ip dhclient 动态分配ip 修改 ifcfg-ens33网卡配置文件  静态分配ip dhclient -r (释放动态分配的ip地址) vi /etc/sysconfig/ne ...

  6. js数据类型及判断数据类型

    众所周知,js有7种数据类型 1. null 2. undefined 3. boolean 4. number 5. string 6. 引用类型(object.array.function) 7. ...

  7. vue + elementui 使用多选按钮实现单选功能

    CommonRadio.vue <template> <div> <el-checkbox-group v-model="checkList" @ch ...

  8. Mac 下 安装Python3

    因为Mac系统自带Python2.7 所以我们开发要重新装Python3 直接运行下面就好 luohaotiandeMacBook-Pro:~ luohaotian$ which python /us ...

  9. Java异常类的继承关系图

  10. 手写一个简易版Tomcat

    前言 Tomcat Write MyTomcat Tomcat是非常流行的Web Server,它还是一个满足Servlet规范的容器.那么想一想,Tomcat和我们的Web应用是什么关系? 从感性上 ...