一. 基础总结

1.Restful服务改造

  Core下的WebApi默认也是Restful格式服务,即通过请求方式(Get,post,put,delete)来区分请求哪个方法,请求的URL中不需要写方法名。 但是我们不喜欢这种方式,所以我们将默认的路由规则 [Route("api/[controller]")] 改为: [Route("api/[controller]/[action]")]

2.基本格式

继承 ControllerBase 类,需要加特性[ApiController].

(1) 特性[ApiController]的作用:

  a.特性路由要求,和[Route]成对出现,有了它,通过 UseMvc 定义的传统路由或通过 Startup.Configure 中的 UseMvcWithDefaultRoute 访问操作均无效。

  b.模型验证错误自动触发 HTTP 400 响应

  c.绑定源参数推理(如果没有 [ApiController] 属性,同时也没有 [FromQuery][FromBody]等 的绑定源属性,ASP.NET Core 运行时会尝试使用复杂对象模型绑定器。)

  d.Multipart/form-data 请求推理

  f.错误状态代码的问题详细信息

(2) 特性[ApiController]的作用位置:

  a.作用于controller

  b.作用于程序集,服务于整个项目。在Startup类上的namespace上添加:[assembly: ApiController]

注:它不能作用action上。

PS:MVC中的Controller类继承ControllerBase类,实现了IActionFilter, IFilterMetadata, IAsyncActionFilter, IDisposable接口。

3.路由规则

  详见  第二十节:Asp.Net Core WebApi和MVC 路由规则比较

4.常见的特性

  [Route] 指定控制器或操作的 URL 模式。

  [Bind] 指定要包含的前缀和属性,以进行模型绑定。

  [HttpGet] [HttpPost]标识支持 HTTP GET 等操作谓词的操作。

  [Consumes] 指定某个操作接受的数据类型。

  [Produces] 指定某个操作返回的数据类型。

5.绑定源参数推理

  [FromBody] 实体JSON格式的获取,和不加效果相同

  [FromForm] 请求正文中的表单数据

  [FromQuery] 请求查询字符串参数,Get请求的时候,用实体接受需要加

  [FromHeader] 请求标头

  [FromRoute] 当前请求中的路由数据

  [FromServices] 作为操作参数插入的请求服务,即将对象注入到方法中

6.允许跨域

  同Core MVC相同,详见:https://www.cnblogs.com/yaopengfei/p/11191938.html

7.过滤器

  同Core MVC相同,详见:https://www.cnblogs.com/yaopengfei/p/11232921.html, 但webapi中页面相关的过滤器不适用

二. Get和Post请求

1. Get请求

  前端JS发送Get请求的时候,后台可以分参数接收,也可以用实体接收,但是需要在实体的前面加上[FromQuery]。

 注:不能用dynamic接收,不管怎么处理都报错。

案例测试:

(1).分参数接收,可以正常访问。

(2).用实体类接收,前面加[FromQuery],可以正常访问(否则报415)。

(3).用dynamic接收,前面什么不加,报错415,前面加[FromQuery],也报错,报500。

服务器端代码:

 1     [Route("api/[controller]/[action]")]2     [ApiController]3     public class FirstController : ControllerBase4     {5         /******************************************下面是测试Get请求的相关方法***************************************************/6 7         [HttpGet]8         public string GetInfor1(string userName, string pwd)9         {
10             return $"{userName}+{pwd}";
11         }
12
13         [HttpGet]
14         public string GetInfor2([FromQuery]UserInfor model)
15         {
16             return $"{model.userName}+{model.pwd}";
17         }
18         [HttpGet]
19         //加上[FromQuery]也报错
20         public string GetInfor3([FromQuery]dynamic model)
21         {
22             return $"{model.userName}+{model.pwd}";
23         }
24
25     }

前端代码:

 1             //一.下面是Get请求的测试2             //1. 分参数接收,可以正常访问3             $("#getBtn1").click(function () {4                 $.ajax({ url: "https://localhost:44387/api/First/GetInfor1", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { console.log(data); } });5             });6             //2. 用实体类接收,前面加[FromQuery],可以正常访问(否则报415)7             $("#getBtn2").click(function () {8                 $.ajax({ url: "https://localhost:44387/api/First/GetInfor2", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { console.log(data); } });9             });
10             //3. 用dynamic接收,前面什么不加,报错415,前面加[FromQuery],也报错,报500
11             $("#getBtn3").click(function () {
12                 $.ajax({ url: "https://localhost:44387/api/First/GetInfor3", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { console.log(data); } });

2. Post请求

  前端JS发送Post请求的时候,可能是表单提交,也可能是JOSN格式提交,所以下面要分情况讨论:默认情况下在我们注入MVC服务时被配置使用的时JsonInputFormatter,即实体默认接受JSON格式的数据,我们如果想让它接受表单数据,需要在实体前面加[FromForm].

(1) 接收JSON格式:实体前面什么也不加 或者 实体前面加[FromBody]

(2) 接收表单格式: 实体前面加[FromForm]

注:不能分参数接收!! 用dynamic接收的时候,只能处理前端JOSN格式的数据,加[FromBody]或者不加都行, 不能处理前端表单格式数据!!

案例测试:

(1).一个参数的情况,后台分参数接收,均拿不到值

(2).表单提交,实体前面什么也不加 或者 实体前面加[FromForm],Login1 和 Login2 均报415,Login3可以正常访问

(3).JSON提交,实体前面加[FromBody],Login1,Login2正常访问,Login3能访问通,但是后台拿不到值,都为空

(4).JOSN格式,后台用dynamic能接收,加[FromBody]或者不加都可以接收

(5).表单格式,后台用dynamic不能接收,加[FromForm]或者不加都报500,报错。

服务器端代码:

 1     [Route("api/[controller]/[action]")]2     [ApiController]3     public class FirstController : ControllerBase4     {5      6         /******************************************下面是测试Post请求的相关方法***************************************************/7 8         [HttpPost]9         public string Login0(string userName)
10         {
11             return $"{userName}";
12         }
13
14         [HttpPost]
15         public string Login1(UserInfor model)
16         {
17             return $"{model.userName}+{model.pwd}";
18         }
19
20         [HttpPost]
21         public string Login2([FromBody]UserInfor model)
22         {
23             return $"{model.userName}+{model.pwd}";
24         }
25
26         [HttpPost]
27         public string Login3([FromForm]UserInfor model)
28         {
29             return $"{model.userName}+{model.pwd}";
30         }
31         [HttpPost]
32         public string Login4([FromBody]dynamic model)
33         {
34             return $"{model.userName}+{model.pwd}";
35         }
36
37         [HttpPost]
38         public string Login5([FromForm]dynamic model)
39         {
40             return $"{model.userName}+{model.pwd}";
41         }
42     }

前端代码:

 1              //二.下面是Post请求的测试2             //(Post请求默认情况下为:ContentType = "application/x-www-form-urlencoded"提交表单的形式,如果要发送JOSN格式,需要加上参数contentType: 'application/json')3             //PS: { userName: "admin", pwd: "123456" } 这就是一个JSON对象,也可以叫实体4 5             //1. 一个参数的情况,后台分参数接收,均拿不到值6             $("#postBtn0").click(function () {7                 //1.1 正常拼接,可以访问通,但是拿不到userName的值8                 //$.ajax({ url: "https://localhost:44387/api/First/Login0", type: "Post", data: { userName: "admin" }, success: function (data) { console.log(data);  } });9                 //1.2 没有键,只有值,可以访问通,但是拿不到userName的值 (这里同.Net 平台下的WebApi不同)
10                 $.ajax({ url: "https://localhost:44387/api/First/Login0", type: "Post", data: { "": "admin" }, success: function (data) { console.log(data); } });
11             });
12
13             //2. 表单提交,Login1 和 Login2 均报415,Login3可以正常访问
14             $("#postBtn1").click(function () {
15                 $.ajax({ url: "https://localhost:44387/api/First/Login1", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { console.log("Login1:" + data); } });
16                 $.ajax({ url: "https://localhost:44387/api/First/Login2", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { console.log("Login2:" + data); } });
17                 $.ajax({ url: "https://localhost:44387/api/First/Login3", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { console.log("Login3:" + data); } });
18             });
19
20             //3.JSON提交,Login1,Login2正常访问,Login3能访问通,但是后台拿不到值,都为空
21             $("#postBtn2").click(function () {
22                 //将post请求指定为contentType: 'application/json',且传递的参数格式化成Json字符串,则可以正常访问
23                 $.ajax({ url: "https://localhost:44387/api/First/Login1", type: "Post", contentType: 'application/json', data: JSON.stringify({ userName: "admin", pwd: "123456" }), success: function (data) { console.log("Login1:" + data); } });
24                 $.ajax({ url: "https://localhost:44387/api/First/Login2", type: "Post", contentType: 'application/json', data: JSON.stringify({ userName: "admin", pwd: "123456" }), success: function (data) { console.log("Login2:" + data); } });
25                 $.ajax({ url: "https://localhost:44387/api/First/Login3", type: "Post", contentType: 'application/json', data: JSON.stringify({ userName: "admin", pwd: "123456" }), success: function (data) { console.log("Login3:" + data); } });
26
27             });
28
29             //4.JOSN格式,后台用dynamic能接收,加[FromBody]或者不加都可以接收
30             $("#postBtn3").click(function () {
31                 //将post请求指定为contentType: 'application/json',且传递的参数格式化成Json字符串,则可以正常访问
32                 $.ajax({ url: "https://localhost:44387/api/First/Login4", type: "Post", contentType: 'application/json', data: JSON.stringify({ userName: "admin", pwd: "123456" }), success: function (data) { console.log("JSON:" + data); } });
33             });
34             //5.表单格式,后台用dynamic不能接收,加[FromForm]或者不加都报500
35             $("#postBtn4").click(function () {
36                 $.ajax({ url: "https://localhost:44387/api/First/Login5", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { console.log("表单:" + data); } });
37             });

3.总结

  Get请求,可以分参数接收,也可以用实体接收,需要在实体的前面加上[FromQuery]。

  POST请求,用实体接收,针对js默认的表单提交方式,实体前面加[FromForm];针对js的JSON格式的提交方式,实体前面什么也不加 或者 实体前面加[FromBody]。

第十三节:Asp.Net Core WebApi基础总结和请求方式-第十八节相关推荐

  1. ASP.NET Core Web APi获取原始请求内容

    前言 我们讲过ASP.NET Core Web APi路由绑定,本节我们来讲讲如何获取客户端请求过来的内容. ASP.NET Core Web APi捕获Request.Body内容 [HttpPos ...

  2. ASP.NET Core WebApi构建API接口服务实战演练

    一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...

  3. ASP.NET CORE WEBAPI文件下载

    最近要使用ASP.NET CORE WEBAPI用来下载文件,使用的.NET CORE 3.1.考虑如下场景: 文件是程序生成的. 文件应该能兼容各种格式. 浏览器可以感知进行下载. 准备 经过简单的 ...

  4. asp.net core webAPI学习笔记(三)资源请求

    IDE 版本:Visual Studio 2017 15.9.7 asp.net core 版本 2.1.1 本文档说明需在 asp.net core webAPI学习笔记(一)项目搭建 的基础下进行 ...

  5. IIS部署asp.net core webapi

    一.需要安装Windows Server Hosting,作用是让IIS有方向代理功能(Asp.Net Core Module负责反向代理工作),将请求转发到Kestrel,Windows serve ...

  6. ASP.Net Core WebApi几种版本控制对比

    ASP.Net Core WebApi几种版本控制对比 原文:ASP.Net Core WebApi几种版本控制对比 一.版本控制的好处: (1)有助于及时推出功能, 而不会破坏现有系统. (2)它还 ...

  7. NET问答: 如何将 ASP.NET Core WebAPI 中抛出的异常封装成对象?

    咨询区 rianjs: 在 ASP.NET Core WebAPI 中,我的 Controller 代码如下: [Route("create-license/{licenseKey}&quo ...

  8. 【源码解读】Vue与ASP.NET Core WebAPI的集成

    在前面博文[Vue]Vue 与 ASP.NET Core WebAPI 的集成中,介绍了集成原理:在中间件管道中注册SPA终端中间件,整个注册过程中,终端中间件会调用node,执行npm start命 ...

  9. 【Vue】Vue与ASP.NET Core WebAPI的集成

    SPA单页面应用已经遍地开花,熟知的三大框架,Angular.Vue和React,其中Angular与React均可集成至ASP.NET Core,且提供了相关了中间件.但是Vue没有: " ...

最新文章

  1. 推荐几个BAT大佬的公众号
  2. Visual Stdio 无法直接启动带有“类库输出类型”的项目若要调试此项目,请在此解决方案中添加一个引用库项目的可执行项目。将这个可执行项目设置为启动项目!
  3. 城市列表简称JSON数据
  4. IOS NSArray 倒序
  5. OpenGL linesmooth线平滑的实例
  6. php子类选择器代码,php – 可变产品选择器:获取实时选定值
  7. 第三次作业:PSP耗时
  8. 你不可不知道的React生命周期
  9. iphone降级_回顾降级系统恢复备份
  10. nginx工作原理详解
  11. 思科模拟器:路由器基本配置
  12. 解决Mac电脑无法读写ntfs硬盘分区的方法以及磁盘读写的简单方法
  13. OpenSSL密码库算法笔记——第 2.2.4章 Barrett模数与相关函数
  14. Windows10更新后耳机没声音
  15. Java全栈工程师学习
  16. oracle trim没用,Oracle中Trim函数的使用方法
  17. 这车模,就一个字:小巧灵动
  18. three.js基础几何体:立方体,球,圆柱的绘制
  19. mysql更新多表sql语句怎么写_MySQL多表updatesql语句总结
  20. springboot+vue+java婚纱摄影预约管理系统ssm

热门文章

  1. BZOJ4293 Siano
  2. python 如何在一个for循环中遍历两个列表
  3. GSON解析JSON
  4. ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)
  5. Python用subprocess的Popen来调用系统命令
  6. 默认构造函数的作用(“A”方法没有采用“0”个参数的重载
  7. 【数据结构与算法】复杂度分析
  8. [签名算法]DSA 算法
  9. linux系统中使用pycharn,在pycharm中使用linux控制台
  10. python单元测试的应用_单元测试pythongui应用程序的推荐方法是什么?