先從一個問題提及,微信小程序按照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){ ... } })
問題還沒完,若是想把全部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請求的一些細節作些說明。
文章中有錯誤的還請留言交流!!!
參考文章: