.net core Web API参数绑定规则
参数推理绑定
先从一个问题说起,微信小程序按照WebAPI定义的参数传递,Get请求服务器端可以正常接收到参数,但是Post请求取不到。
Web API代码(.netcore 3.1)如下:
[HttpGet("Login")]
public LoginResult Login(string code)
{
...
}
[HttpPost("PostAvatar")]
public BaseResult<string> PostAvatar(int id,string imgUrl)
{
...
}
客户端代码(微信小程序js)如下:
wx.request({
url: '/api/Login',
data:{code:'xxx'},
method:'GET',
success:function(res){}
})
wx.request({
url: '/api/PostAvatar',
data: { id: 1,imgUrl:'xxx' },
method: 'POST',
success: function (res) { }
})
后来发现如果把参数放在一个实体里就可以接收到,像这样
[HttpPost("PostAvatar")]
public BaseResult<string> PostAvatar(Avatar model)
{
...
}
...
public class Avatar
{
public int Id { get; set; }
public string imgUrl{ get; set; }
}
于是找到官方文档对于绑定源参数推理的解释:
WEB API存在以下绑定源特性:
[FromBody] 请求正文
[FromForm] 请求正文中的表单数据
[FromHeader] 请求标头
[FromQuery] 请求查询字符串参数
[FromRoute] 当前请求中的路由数据
[FromServices] 作为操作参数插入的请求服务
Web API 还有一套默认的推理规则,意思就是上面的这些特性可以加在参数的前面用来强制的指定这个参数是用那种方式获取,但是如果不显式的声明,它会按照这套规则默认匹配。规则如下:
绑定源推理规则的行为如下:
[FromBody] 针对复杂类型参数进行推断。 [FromBody] 不适用于具有特殊含义的任何复杂的内置类型,如 IFormCollection 和 CancellationToken。 绑定源推理代码将忽略这些特殊类型。
[FromForm] 针对 IFormFile 和 IFormFileCollection 类型的操作参数进行推断。 该特性不针对任何简单类型或用户定义类型进行推断。
[FromRoute] 针对与路由模板中的参数相匹配的任何操作参数名称进行推断。 当多个路由与一个操作参数匹配时,任何路由值都视为 [FromRoute]。
[FromQuery] 针对任何其他操作参数进行推断。
默认按照从上到下的顺序去匹配,最后才是FromQuery,所以最开始的问题就解释通了,因为简单类型的参数如果不显式指定类型就是从Query里取,而我们的用的post请求方式,参数都在body里所以服务器接收不到。
简单类型、复杂类型混合
知道了上面的推理规则,所以下面的这个例子里,wechat参数因为是简单类型所以不会跟其他的参数在一起,必须放在URL里。
[HttpPost("PostAvatar")]
public BaseResult<string> PostAvatar(Avatar model,int wechat)
{
...
}
...
public class Avatar
{
public int id { get; set; }
public string imgUrl{ get; set; }
}
js的请求必须是这样才行
wx.request({
url: '/api/PostAvatar?wechat=1',//增加在这
data:{
id:1,
imgUrl:'',
//wechat:1 放在data里一样取不到
},
method:"POST",
success:function(res){
...
}
})
空key问题
问题还没完,如果想把所有POST请求使用统一的格式,单个参数也想放在body里请求,是不是按照上面的绑定规则显式指定为FromBody就可以呢?
public IActionResult Post([FromBody] string name) { ... }
答案是:依然取不到,因为js发送的body是这样的
{"name":"xxxx"}
而webapi期望的body里只有xxxx。
总结
Web API 参数的绑定如果不是显式的指定会按照一定默认规则识别参数的来源,GET请求比较简单从QueryString中取值,POST请求会因为参数的类型有所不同。
[FromBody]
和[FromForm]
还是有些差别的,涉及到了ContentType后续可能还会针对HTTP请求的一些细节做些说明。
文章中有错误的还请留言交流!!!
参考文章:
.net core Web API参数绑定规则的更多相关文章
- 细说 Web API参数绑定和模型绑定
今天跟大家分享下在Asp.NET Web API中Controller是如何解析从客户端传递过来的数据,然后赋值给Controller的参数的,也就是参数绑定和模型绑定. Web API参数绑定就是简 ...
- Parameter Binding in ASP.NET Web API(参数绑定)
Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...
- Web API(四):Web API参数绑定
在这篇文章中,我们将学习Web API如何将HTTP请求数据绑定到一个操作方法的参数中. 操作方法在Web API控制器中可以有一个或多个不同类型的参数.它可以是基本数据类型或复杂类型.Web API ...
- Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文主要来讲解以下内容: ...
- 一张图说明 Web Api 参数绑定默认规则
请求如下: 控制器如下: 慎重说明:不管请求方式是 get 还是 post , 简单类型的参数,如 name 和 id ,其值都是从 url 里面去取. Web API 从 url 还是 body 获 ...
- .NET Core WEB API接口参数模型绑定
.NET Core WEB API 模型绑定方式有以下表格中的几种: 特性 绑定源 [FromHeader] 请求标头 [FromQuery] 请求查询字符串参数 [FromForm] 请求正文中的表 ...
- ASP.NET Core Web APi获取原始请求内容
前言 我们讲过ASP.NET Core Web APi路由绑定,本节我们来讲讲如何获取客户端请求过来的内容. ASP.NET Core Web APi捕获Request.Body内容 [HttpPos ...
- .NET Core WEB API中接口参数的模型绑定的理解
在.NET Core WEB API中参数的模型绑定方式有以下表格中的几种: 微软官方文档说明地址:https://docs.microsoft.com/zh-cn/aspnet/core/web-a ...
- 在ASP.NET Core Web API中为RESTful服务增加对HAL的支持
HAL(Hypertext Application Language,超文本应用语言)是一种RESTful API的数据格式风格,为RESTful API的设计提供了接口规范,同时也降低了客户端与服务 ...
随机推荐
- Java实现 蓝桥杯VIP 算法提高 3-2字符串输入输出函数
算法提高 3-2字符串输入输出函数 时间限制:1.0s 内存限制:512.0MB 描述 编写函数GetReal和GetString,在main函数中分别调用这两个函数.在读入一个实数和一个字符串后,将 ...
- java实现Kruskal算法
1 问题描述 何为Kruskal算法? 该算法功能:求取加权连通图的最小生成树.假设加权连通图有n个顶点,那么其最小生成树有且仅有n - 1条边. 该算法核心思想:从给定加权连通图中,选择当前未被选择 ...
- java实现角谷步数
你听说过角谷猜想吗? 任意的正整数,比如 5, 我们从它开始,如下规则计算: 如果是偶数,则除以2,如果是奇数,则乘以3再加1. 如此循环,最终必会得到"1" ! 比如 5 的处理 ...
- java实现数字黑洞
任意一个 5 位数,比如:34256,把它的各位数字打乱,重新排列,可以得到 一个最大的数:65432,一个最小的数 23456. 求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不 ...
- 纯正中文版本pi-star系统下载
基于3.4.17修改(稳定,发热量少) 不支持RPI 4 a/b+ 完美支持树莓派0,1,2,3 默认刷好卡,启动已经设置好所有参数(选好TFT屏幕,调制解调器类型GPIO,打开了DMR服务器(460 ...
- range用法(倒序取值)
range(4,-1,-1) #倒数取值 ''' start: 计数从 start 开始.默认是从 0 开始.例如range(5)等价于range(0, 5); stop: 计数到 stop 结束,但 ...
- numpy.stack和numpy.concatenate的区别
在使用numpy进行矩阵运算的时候踩到的坑,原因是不能正确区分numpy.concatenate和numpy.stack在功能上的差异. 先说numpy.concatenate,直接看文档: nump ...
- navicat 出现 mysql远程连接问题 Lost connection to MySQL server at ‘reading initial communication packet', system error: 0
今天做服务器上的东西需要看数据库时,突然发现有这个报错,然后自己也查了很多资料 我最后找到一个在my,cnf配置文件中mysqld下加入一条 max_allowed_packet = 500M 也就是 ...
- mac App 破解之路六 studio 3t
不想无限使用,直接破解到正版: 输入邮箱 名字之后 还有licence信息之后,处理函数是: this.text.getText() 很明显是你输入的licence. 然后交给父类okPress处 ...
- cb16a_c++_顺序容器的选用_排序_二分查找
/*cb16a_c++_顺序容器的选用_排序_二分查找顺序容器: 1.vector的优点与缺点 vector优点:排序利用下标,快速排序,做二分查找非常快 2.list的优点与缺点 list优点:插入 ...