原因
經常有朋友遇到webapi參數傳遞問題,自己也碰到過一些坑,在此記錄下正確的姿勢,簡單參數傳遞相信沒有人會有問題,容易出現問題的是對象參數和表單參數。
1、WebApi5.2.3有FromBody和無FromBody
控制器代碼如下:
public class ValuesController : ApiController { // POST api/values [HttpPost] [Route("~/api/Values/Post")] public UserModel Post(UserModel value) { return value; } [HttpPost] [Route("~/api/Values/Put")] // PUT api/values/5 public UserModel Put([FromBody]UserModel value) { return value; } } public class UserModel { public string UserName { get; set; } public string Password { get; set; } }
對應的JS請求代碼如下,對於有FromBody的Put請求來說,兩種請求方式都是可以的:
<script type="text/javascript"> $(function () { $('#btnPost').click(function () { $.ajax({ url: '/api/Values/Post', data: { UserName: 'Admin', Password: '123456' }, method: 'POST', dataType: 'json' }).done(function (result) { $('#txtPost').val(JSON.stringify(result)); }) }) $('#btnPostFromBody').click(function () { $.ajax({ url: '/api/Values/Put', data: { UserName: 'Admin', Password: '123456' }, method: 'POST', dataType: 'json' }).done(function (result) { $('#txtPostFromBody').val(JSON.stringify(result)); }) $.ajax({ url: '/api/Values/Put', data: JSON.stringify({ UserName: 'Admin', Password: '123456' }), method: 'POST', dataType: 'json', contentType: 'application/json' }).done(function (result) { $('#txtPostFromBody').val(JSON.stringify(result)); }) }) })
有圖有真相

2、Asp .Net Core 有FromBody和無FromBody
服務端代碼如下:
public class ValuesController : Controller { // POST api/values [HttpPost] [Route("~/api/Values/Post")] public UserModel Post(UserModel value) { return value; } [HttpPost] [Route("~/api/Values/Put")] // PUT api/values/5 public UserModel Put([FromBody]UserModel value) { return value; } } public class UserModel { public string UserName { get; set; } public string Password { get; set; } }
js請求代碼有所不同,FromBody不再提供兼容支持 只能采用application/json方式提交:
$('#btnPost').click(function () {
$.ajax({
url: '/api/Values/Post',
data: {
UserName: 'Admin',
Password: '123456'
},
method: 'POST',
dataType: 'json'
}).done(function (result) {
$('#txtPost').val(JSON.stringify(result));
})
})
$('#btnPostFromBody').click(function () {
$.ajax({
url: '/api/Values/Put',
data: JSON.stringify({
UserName: 'Admin',
Password: '123456'
}),
method: 'POST',
dataType: 'json',
contentType: 'application/json'
}).done(function (result) {
$('#txtPostFromBody').val(JSON.stringify(result));
})
})
調用結果:

3、Asp .Net Core 之From表單
有時候難免有上傳文件的需求,對象存儲這個嘛有的時候客戶不願意多花錢或者把文件存到別人的服務器上,只能自己存了。為了少點垃圾文件還是和表單一起提交吧。
控制器代碼:

js請求代碼,注意紅字:
$('#btnFromForm').click(function () {
var data = new FormData();
data.append('UserName', 'Admin');
data.append('Password', '123456');
data.append('Photo', document.getElementById('txtPhoto').files[0]);
$.ajax({
url: '/api/Values/RegisterUser',
data: data,
method: 'POST',
dataType: 'json',
contentType: false,
processData: false
}).done(function (result) {
$('#txtFromForm').val(JSON.stringify(result));
})
})
請求結果:

最后說一句:接口的參數如果是對象,參數名一定不能與改對象的屬性名相同(不區分大小寫),否則屬性的值會全部為null,我猜是微軟認為有循環依賴了。比如以上例子中,UserModel中含有UserName,Password,Photo屬性,則接口中UserModel參數的名字一定不能是UserName,Password,Photo(不區分大小寫),曾經被這個問題坑了2天。
