参数推理绑定

先从一个问题说起,微信小程序按照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参数绑定规则的更多相关文章

  1. 细说 Web API参数绑定和模型绑定

    今天跟大家分享下在Asp.NET Web API中Controller是如何解析从客户端传递过来的数据,然后赋值给Controller的参数的,也就是参数绑定和模型绑定. Web API参数绑定就是简 ...

  2. Parameter Binding in ASP.NET Web API(参数绑定)

    Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...

  3. Web API(四):Web API参数绑定

    在这篇文章中,我们将学习Web API如何将HTTP请求数据绑定到一个操作方法的参数中. 操作方法在Web API控制器中可以有一个或多个不同类型的参数.它可以是基本数据类型或复杂类型.Web API ...

  4. 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. 本文主要来讲解以下内容: ...

  5. 一张图说明 Web Api 参数绑定默认规则

    请求如下: 控制器如下: 慎重说明:不管请求方式是 get 还是 post , 简单类型的参数,如 name 和 id ,其值都是从 url 里面去取. Web API 从 url 还是 body 获 ...

  6. .NET Core WEB API接口参数模型绑定

    .NET Core WEB API 模型绑定方式有以下表格中的几种: 特性 绑定源 [FromHeader] 请求标头 [FromQuery] 请求查询字符串参数 [FromForm] 请求正文中的表 ...

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

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

  8. .NET Core WEB API中接口参数的模型绑定的理解

    在.NET Core WEB API中参数的模型绑定方式有以下表格中的几种: 微软官方文档说明地址:https://docs.microsoft.com/zh-cn/aspnet/core/web-a ...

  9. 在ASP.NET Core Web API中为RESTful服务增加对HAL的支持

    HAL(Hypertext Application Language,超文本应用语言)是一种RESTful API的数据格式风格,为RESTful API的设计提供了接口规范,同时也降低了客户端与服务 ...

随机推荐

  1. Java实现猜底牌问题(贪婪法)

    1 问题描述 设计一种策略,使在下面的游戏中,期望提问的次数达到最小.有一副纸牌,是由1张A,2张2,3张3,-9张9组成的,一共包含45张牌.有人从这副牌洗过的牌中抽出一张牌,问一连串可以回答是或否 ...

  2. java实现第六届蓝桥杯打印大X

    打印大X 打印大X 小明希望用星号拼凑,打印出一个大X,他要求能够控制笔画的宽度和整个字的高度. 为了便于比对空格,所有的空白位置都以句点符来代替. 要求输入两个整数m n,表示笔的宽度,X的高度.用 ...

  3. java实现第五届蓝桥杯锦标赛

    锦标赛 这题小编能力有限,还望大佬解决 题目描述 如果要在n个数据中挑选出第一大和第二大的数据(要求输出数据所在位置和值),使用什么方法比较的次数最少?我们可以从体育锦标赛中受到启发. 如图[1.pn ...

  4. webpack+vue+.vue组件模板文件 所需要的包

    {  "name": "webpack-study02",  "version": "1.0.0",  "de ...

  5. chrome浏览器版本与驱动不匹配问题的解决办法

    1.浏览器与驱动如何匹配才不会报错 使用selenium模块的webdriver打开谷歌浏览器时常遇到这样的错误提示: selenium.common.exceptions.WebDriverExce ...

  6. 没有国产主机,怎么开发:交叉编译和QEMU虚拟机

    1. 背景 近期国产化的趋势越来越浓,包括国产操作系统.国产CPU等.时隔十多年,QQ for Linux也更新了.做为软件开发人员,"有幸"也需要适配国产化.至于国产化的意义等就 ...

  7. Node.js 学习笔记(一)

    node.js说白了就是JavaScript. node.js的性能是php的86倍(大概). 在下载完后可以用命令行打开及运行.   什么是 Web 服务器? Web服务器一般指网站服务器,是指驻留 ...

  8. group by <grouping sets(...) ><cube(...)>

    GROUP BY      GROUPING SETS() 后面将还会写学习 with cube,  with rollup,以及将它们转换为标准的GROUP BY的子句GROUP SET(), CU ...

  9. log报错的原因解决

    idea未装lombok的插件: 1.用快捷键Ctrl+Alt+S打开:Settings→Plugins→Browse repositories 2.输入lom后选择Install,安装插件 3.按照 ...

  10. leetcode-cn 剑指offer

    目录 面试题06 从尾到头打印链表 面试题07 重建二叉树 面试题09 用两个栈实现队列 面试题10- I 斐波那契数列 面试题11 旋转数组的最小数字 面试题12. 矩阵中的路径 面试题52. 两个 ...