一. 基本调用规则

1. 前提

  WebApi的默认路由规则为:routeTemplate: "api/{controller}/{id}", 下面为我们统一将它改为 routeTemplate: "api/{controller}/{action}/{id}",这样我们在调用的时候,还是通过拼接方法名来识别,不用考虑上面的坑别的规则了,这里我单纯的来探讨WebApi的传参和调用。

2. 基本的调用规则

  是什么请求,在方法上面标注什么特性,常见的有[HttpGet][HttpPost][HttpPut][HttpDelete]。

PS:方法名以Get、Post、Put、Delete开头,WebApi会自动默认这个请求就是Get、Post、Put、Delete请求,而如果你以其他名称开头而又不标注方法的请求方式,那么这个时候服务器虽然找到了这个方法,但是由于请求方式不确定,所以直接返回给你405——方法不被允许的错误。

二. Get请求规则

1. 标准用法:

  发起请求的方式都为 api/Second/CheckLogin?userName=admin&pwd=123456 这种类型,不管几个参数(1个或多个),接收的时候,如果是分参数接收,没有任何问题, 可以正常接收,但如果是通过实体类来接收,必须在前面加特性[FromUri],否则接收不到。

PS:当然也可以什么参数都不写,通过传统的Request或者Request.QueryString来接受。

2. 实战测试:

(1). 分别调用CheckLogin1、CheckLogin2、CheckLogin3方法, 发现前两个方法都能正常调用,CheckLogin3这个方法报错, 报:"Message":"出现错误","ExceptionMessage":"未将对象引用设置到对象的实例"。

(2). 调用CheckLogin4方法,报与上面相同的错误,证明dynamic类型也不能这么用。

(3). 调用CheckLogin5方法,能正常接收,表明可以通过传统的Request或者Request.QueryString来接受。

代码分享:

1   public class LoginModel
2     {
3         public string userName { get; set; }
4
5         public string pwd { get; set; }
6     }

  1         #region 01-分参数接收2         /// <summary>3         /// Get api/Second/CheckLogin1?userName=admin&pwd=1234564         /// </summary>5         /// <param name="userName"></param>6         /// <param name="pwd"></param>7         /// <returns></returns>8         [HttpGet]9         public string CheckLogin1(string userName, string pwd)10         {11             if (userName == "admin" && pwd == "123456")12             {13                 return "ok";14             }15             else16             {17                 return "error";18             }19         }20         #endregion21 22         #region 02-用实体接收,加[FromUri]特性23         /// <summary>24         /// Get api/Second/CheckLogin2?userName=admin&pwd=12345625         /// </summary>26         /// <param name="model"></param>27         /// <returns></returns>28         [HttpGet]29         public string CheckLogin2([FromUri]LoginModel model)30         {31             if (model.userName == "admin" && model.pwd == "123456")32             {33                 return "ok";34             }35             else36             {37                 return "error";38             }39         }40         #endregion41 42         #region 03-用实体接收,不加[FromUri]特性43         /// <summary>44         /// Get api/Second/CheckLogin3?userName=admin&pwd=12345645         /// </summary>46         /// <param name="model"></param>47         /// <returns></returns>48         [HttpGet]49         public string CheckLogin3(LoginModel model)50         {51             if (model.userName == "admin" && model.pwd == "123456")52             {53                 return "ok";54             }55             else56             {57                 return "error";58             }59         }60         #endregion61 62         #region 04-用dynamic接收,加[FromUri]特性63         /// <summary>64         /// Get api/Second/CheckLogin4?userName=admin&pwd=12345665         /// </summary>66         /// <param name="model"></param>67         /// <returns></returns>68         [HttpGet]69         public string CheckLogin4([FromUri]dynamic model)70         {71             if (model.userName == "admin" && model.pwd == "123456")72             {73                 return "ok";74             }75             else76             {77                 return "error";78             }79         }80         #endregion81 82         #region 05-没有任何参数,直接用Request相关方法接收83         /// <summary>84         /// Get api/Second/CheckLogin5?userName=admin&pwd=12345685         /// </summary>86         /// <param name="model"></param>87         /// <returns></returns>88         [HttpGet]89         public string CheckLogin5()90         {91             var userName = HttpContext.Current.Request["userName"];92             var pwd = HttpContext.Current.Request.QueryString["pwd"];93             if (userName == "admin" && pwd == "123456")94             {95                 return "ok";96             }97             else98             {99                 return "error";
100             }
101         }
102         #endregion

 1   //一.下面是Get请求的测试2             //1. 分参数接收,可以正常访问3             $("#getBtn1").click(function () {4                 $.ajax({ url: "/api/Second/CheckLogin1", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });5             });6             //2. 用实体类接收,前面加[FromUrl],可以正常访问7             $("#getBtn2").click(function () {8                 $.ajax({ url: "/api/Second/CheckLogin2", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });9             });
10             //3. 用实体类接收,前面什么不加,报错
11             // "Message":"出现错误","ExceptionMessage":"未将对象引用设置到对象的实例"
12             $("#getBtn3").click(function () {
13                 $.ajax({ url: "/api/Second/CheckLogin3", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });
14             });
15             //4. 用dynamic接收,前面什么不加,报错
16             // "Message":"出现错误","ExceptionMessage":"未将对象引用设置到对象的实例"
17             $("#getBtn4").click(function () {
18                 $.ajax({ url: "/api/Second/CheckLogin4", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });
19             });
20             //5. 后台直接用Request或者Request.QueryString,能正常接收
21             $("#getBtn5").click(function () {
22                 $.ajax({ url: "/api/Second/CheckLogin5", type: "get", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });
23             });

3. 特别说明:

  建议忘掉实战测试中的几种错误情况,记住标准用法即可。

三. Post请求规则

1.标准用法:

  参数一定要用“实体类”接收(即使一个参数也要封装实体类),客户端既可以用ContentType="application/x-www-form-urlencoded"提交表单,也可以用 ContentType ="application/json"提交, 模型类前面可以加[FromBody],但只能在一个参数前面加.

2.实战测试

(1). 当只有一个参数的情况,且加[FromBody]特性,不封装实体,如Register0,正常的键值对 { userName: "admin" }能访问通,但后台拿不到值,只有省掉键名{ "": "admin" },才能正常访问,且后台能拿到值。

(2). 多个参数的情况,后台分参数接收,如Register1,正常的键值对提交,无法访问,提示找不到匹配的资源。

(3). 一个或多个参数的情况,后台用实体接收,如Register2,且加[FromBody]特性,可以正常访问,并获取到请求值。

  ①:默认的post请求,即ContentType="application/x-www-form-urlencoded"的形式,可以正常请求。

  ②:将post请求指定为contentType: 'application/json',且传递的实体格式化成Json字符串,则可以正常请求。

(4). 一个或多个参数的情况,后台用dynamic接收,且加[FromBody]特性,需要分情况讨论。

  ①:默认的post请求,即ContentType="application/x-www-form-urlencoded"的形式,服务器报500错误。

  ②:将post请求指定为contentType: 'application/json',且传递的实体格式化成Json字符串,则可以正常请求。

阶段总结:后台用实体接收和用dynamic类型接收,用实体接收,无论是"application/x-www-form-urlencoded"还是"application/json"都能访问;如果用dynamic类型接收,只有"application/json"能访问, 且参数必须是序列化后的字符串

(5). 一个或多个参数的情况,没有参数,如Register4,通过Request或者Request.Form相关方法可以获取请求值。

代码分享:

 1  #region 01-单个参数,加[FromBody]特性2         [HttpPost]3         public string Register0([FromBody]string userName)4         {5             if (userName == "admin")6             {7                 return "ok";8             }9             else
10             {
11                 return "error";
12             }
13         }
14         #endregion
15
16         #region 02-多个参数,分参数接收
17         [HttpPost]
18         public string Register1(string userName, string pwd)
19         {
20             if (userName == "admin" && pwd == "123456")
21             {
22                 return "ok";
23             }
24             else
25             {
26                 return "error";
27             }
28         }
29         #endregion
30
31         #region 03-用实体接收,加[FromBody]特性
32         [HttpPost]
33         public string Register2([FromBody]LoginModel model)
34         {
35             if (model.userName == "admin" && model.pwd == "123456")
36             {
37                 return "ok";
38             }
39             else
40             {
41                 return "error";
42             }
43         }
44         #endregion
45
46         #region 04-用dynamic接收,加[FromBody]特性
47         [HttpPost]
48         public string Register3([FromBody]dynamic model)
49         {
50             if (model.userName == "admin" && model.pwd == "123456")
51             {
52                 return "ok";
53             }
54             else
55             {
56                 return "error";
57             }
58         }
59         #endregion
60
61         #region 05-没有任何参数,直接用Request相关方法接收
62         [HttpPost]
63         public string Register4()
64         {
65             var userName = HttpContext.Current.Request["userName"];
66             var pwd = HttpContext.Current.Request.Form["pwd"];
67             if (userName == "admin" && pwd == "123456")
68             {
69                 return "ok";
70             }
71             else
72             {
73                 return "error";
74             }
75         }
76         #endregion
77
78
79     }

 1  //二.下面是Post请求的测试(默认情况下为:ContentType="application/x-www-form-urlencoded"提交表单的形式)2             //PS: { userName: "admin", pwd: "123456" } 这就是一个JSON对象,也可以叫实体3 4             //1. 一个参数的情况,后台分参数接收,且必须加[FromBody]特性5             $("#postBtn0").click(function () {6                 //1.1 正常拼接,可以访问通,但是拿不到userName的值7                 $.ajax({ url: "/api/Second/Register0", type: "Post", data: { userName: "admin" }, success: function (data) { alert(data); } });8                 //1.2 没有键,只有值,可以正常访问,能拿到userName的值9                 //$.ajax({ url: "/api/Second/Register0", type: "Post", data: { "": "admin" }, success: function (data) { alert(data); } });
10             });
11             //2. 多个参数的情况,后台分参数接收,正常的键值对提交,无法访问,找不到匹配的资源
12             $("#postBtn1").click(function () {
13                 //访问不通
14                 $.ajax({ url: "/api/Second/Register1", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });
15             });
16             //3. 一个或多个参数的情况,后台用实体接收,且加[FromBody]特性,可以正常访问,并获取到请求值
17             $("#postBtn2").click(function () {
18                 //情况①,默认的post请求,即ContentType="application/x-www-form-urlencoded"的形式,可以正常请求
19                 //$.ajax({ url: "/api/Second/Register2", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });
20
21                 //情况②,将post请求指定为contentType: 'application/json',且传递的参数格式化成Json字符串,则可以正常访问
22                 $.ajax({ url: "/api/Second/Register2", type: "Post", contentType: 'application/json', data: JSON.stringify({ userName: "admin", pwd: "123456" }), success: function (data) { alert(data); } });
23
24             });
25             //4. 一个或多个参数的情况,后台用dynamic接收,且加[FromBody]特性,需要分情况讨论
26             $("#postBtn3").click(function () {
27                 //情况①,默认的post请求,即ContentType="application/x-www-form-urlencoded"的形式,服务器报500错误
28                 //$.ajax({ url: "/api/Second/Register3", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });
29
30                 //情况②,将post请求指定为contentType: 'application/json',且传递的参数格式化成Json字符串,则可以正常访问
31                 $.ajax({ url: "/api/Second/Register3", type: "Post", contentType: 'application/json', data: JSON.stringify({ userName: "admin", pwd: "123456" }), success: function (data) { alert(data); } });
32             });
33             //5. 一个或多个参数的情况,没有参数,通过Request或者Request.Form相关方法可以获取请求值
34             $("#postBtn4").click(function () {
35                 //访问不通
36                 $.ajax({ url: "/api/Second/Register4", type: "Post", data: { userName: "admin", pwd: "123456" }, success: function (data) { alert(data); } });
37             });

四. 总结

  Put和Delete请求与Post请求的规则相同,另外还有很多极端的情况,不探讨了,掌握正确的用法,直接去用最佳用法即可。

  总结:记住Get请求和Post请求的标准用法以及基本的调用规则,其他坑爹的情况,可以统统忘记了,注意的是ajax的Get请求,加上一个当前时间或者随机数的参数,使用HttpClient 等需要禁用缓存。

第二节:如何正确使用WebApi和使用过程中的一些坑相关推荐

  1. 第6章第1节:基本设计理论:幻灯片设计过程中的七个常见技巧 [PowerPoint精美幻灯片实战教程]

    在制作演示文稿时,需要掌握一些常见的设计技巧.例如对于幻灯片的配色来说,要尽量使用企业VI中的标准色系. 当前页面的背景颜色,也是取自企业Logo中的标准色. 一张幻灯片应该只讲述一个主题,例如当前的 ...

  2. LayUI treetable树形表格的实现, 数据格式正确,不显示的解决方案 和在这个过程中遇到的坑~ 认真看 你会得到一些想要的答案。

    先给大家看下效果吧! 我这边只是针对数据显示的问题做了解释.并没有增删改查.找增删改查的同学可以不用看了. 做出这样的效果,首先我们要借用LayUI的内置插件,treetable.js 网上有很多,之 ...

  3. 第二节:SpingBoot单元测试

    SpingBoot 365计划开始更新了,计划手敲365个SpringBoot案例回顾总结形成知识体系.目前已经输出了32节的内容.所有源码托管在GitHub和Gitee上. 1.第一节:创建Spri ...

  4. wincc不正确的过程数据服务器,WinCC安装过程中的问题及其解决办法

    西门子的工控软件,尤其像WinCC安装起来有时候并不是那么顺手,可能会遇到各种问题.WinCC安装之前,硬件和软件都应该正确配置,在安装过程中,WinCC安装程序会注意检查是否满足以下安装条件: 1. ...

  5. 第二节认识计算机教案,第二章 第二节 局域网的构建 教学设计_博客

    <第二章 第二节 局域网的构建 教学设计_博客>由会员分享,可在线阅读,更多相关<第二章 第二节 局域网的构建 教学设计_博客(3页珍藏版)>请在装配图网上搜索. 1.第二章 ...

  6. c++ 传智课件_沪科版初中物理九年级全册第二节 科学探究:物质的比热容公开课优质课课件教案视频...

    第十二章 温度与物态变化PPT课件教案下载_初中物理沪科版九年级全一册师梦圆​第一节 温度与温度计PPT课件教案下载_初中物理沪科版九年级全一册师梦圆​第二节 熔化与凝固PPT课件教案下载_初中物理沪 ...

  7. GO语言-第二节-顺序编程

    目录 2.1变量 2.1.1变量声明 2.1.2 变量初始化 2.1.3 变量赋值 2.1.4 匿名变量 2.2 常量 2.2.1 字面常量 2.2.2 常量定义 2.2.3 预定义常量 2.2.4 ...

  8. iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门

    iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门 文章目录 iHRM 人力资源管理系统_第9章_文件上传与PDF报表入门_第二节_PDF报表入门 PDF报表入门 3 ...

  9. 【文献阅读】翻译王军武老师的文献--《稠密气固流的连续理论现状回顾》三、第二节 气固流态化的多尺度模拟

    2. 气固流态化的多尺度模拟 流化床中的气固流动出了名的难以建模.这主要是由于物理定律所在的微尺度与介尺度之间,乃至于与我们希望理解的宏观现象之间的时空鸿沟的存在.这一鸿沟的存在意味着给出多尺度模拟策 ...

最新文章

  1. 反季大清仓,最低仅需34.9元
  2. 华为程序员发现孩子不是自己的!怒提离婚!但老婆只要房子车子!不要孩子!绿他的竟然是个酒吧混混!...
  3. UVa 11100 旅行2007
  4. C#下把txt文件数据读进sql server中存储所遇到的乱码问题
  5. 如何更改vs默认调试浏览器
  6. arcengine 加载地图不显示_用LSV下载城市地图、全省地图教程
  7. IntersectionObserve初试
  8. php声明一个类的关键字,php中怎么实例化一个类
  9. 它打败了欧几里得空间,踹飞了数学怪物,成为全世界的焦点
  10. 学习《数据结构》要爬的第一步梯子
  11. CVPR | 历届CVPR最佳论文收录集锦
  12. 自定义filter中配置不被过滤的资源
  13. `find -name`模式匹配多个模式
  14. android tabhost 生命周期,FragmentTabHost + FragmentLayout布局框架,Fragment生命周期
  15. 大数据技术 - 学习之路(一)
  16. python构建电商用户画像(1)
  17. css 属性 position:sticky (粘滞的) 制作导航吸顶效果
  18. 题解 P4147 【玉蟾宫】
  19. java程序假死_分析一个常见的java多线程通信问题(假死现象)
  20. 制作简单的星星评分案例

热门文章

  1. 洛谷 - P2181 - 对角线 - 打表 - 组合数学
  2. 用JavaScript语言判断一个三位数是否为水仙花数
  3. Linux的#和$区别
  4. 【推荐】介绍两款Windows资源管理器,Q-Dir 与 FreeCommander XE(比TotalCommander更易用的免费资源管理器)...
  5. C函数的实现(strcpy,atoi,atof,itoa,reverse)
  6. 【转】Windows服务调试技巧
  7. 国外好的软件测试网站
  8. xvhfeng的工作回忆总结(第二年)阅读手记
  9. LinkedList专题3
  10. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第9篇]香农对熵和信息的定义是什么?