.net core Web API参数绑定规则

参数推理绑定

先从一个问题提及,微信小程序按照WebAPI定义的参数传递,Get请求服务器端能够正常接收到参数,可是Post请求取不到。
Web API代码(.netcore 3.1)以下:
html

[HttpGet("Login")]
public LoginResult Login(string code)
{
  ...
}
[HttpPost("PostAvatar")]
public BaseResult<string> PostAvatar(int id,string imgUrl)
{
...
}

客户端代码(微信小程序js)以下:git

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) { }
    })

后来发现若是把参数放在一个实体里就能够接收到,像这样github

[HttpPost("PostAvatar")]
public BaseResult<string> PostAvatar(Avatar model)
{
...
}
...
public class Avatar 
{
   public int Id { get; set; }
   public string imgUrl{ get; set; }
}

因而找到官方文档对于绑定源参数推理的解释:web

WEB API存在如下绑定源特性:
[FromBody] 请求正文
[FromForm] 请求正文中的表单数据
[FromHeader] 请求标头
[FromQuery] 请求查询字符串参数
[FromRoute] 当前请求中的路由数据
[FromServices] 做为操做参数插入的请求服务





小程序

Web API 还有一套默认的推理规则,意思就是上面的这些特性能够加在参数的前面用来强制的指定这个参数是用那种方式获取,可是若是不显式的声明,它会按照这套规则默认匹配。规则以下:微信小程序

绑定源推理规则的行为以下:
[FromBody] 针对复杂类型参数进行推断。 [FromBody] 不适用于具备特殊含义的任何复杂的内置类型,如 IFormCollection 和 CancellationToken。 绑定源推理代码将忽略这些特殊类型。
[FromForm] 针对 IFormFile 和 IFormFileCollection 类型的操做参数进行推断。 该特性不针对任何简单类型或用户定义类型进行推断。
[FromRoute] 针对与路由模板中的参数相匹配的任何操做参数名称进行推断。 当多个路由与一个操做参数匹配时,任何路由值都视为 [FromRoute]。
[FromQuery] 针对任何其余操做参数进行推断。



api

默认按照从上到下的顺序去匹配,最后才是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的请求必须是这样才行post

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请求的一些细节作些说明。

文章中有错误的还请留言交流!!!

参考文章:

相关文章
相关标签/搜索