.NET Core 3.1 MVC控制器接收AJAX传递的JSON参数为null如何解决
问题原因
.NET Core 3.1 的默认模型绑定规则和 .NET Framework 存在差异:对于 contentType: application/json 的 POST 请求,默认仅会把请求体的JSON数据绑定到复杂类型参数,简单类型(如string、int等)默认会优先从路由、查询参数中读取,不会自动匹配请求体里的JSON属性,所以你会遇到请求能命中控制器但参数为null的情况。
解决方法(三选一即可,都是极简修改)
方案1:仅修改前端代码,后端完全不用调整
删掉AJAX里的contentType配置,同时不对数据做JSON序列化,用默认的表单格式提交即可,.NET Core 可以直接绑定表单字段到简单参数:
var obj = { send: 'test' }; $.ajax({ url: '/Countries/GetVotes', type: 'POST', // 移除原来的 contentType: "application/json" 配置 data: obj, // 移除JSON.stringify包裹 success: function (data) { if (data === null) { // TODO } else { console.log(data); } }, error: function (error) { console.log(error); } });
方案2:仅修改后端代码,前端完全不用动
- 新增一个极简的接收参数模型类(可直接放在控制器同文件内,不需要单独建文件):
public class GetVotesRequest { public string Send { get; set; } }
- 调整控制器方法的参数,加上
[FromBody]特性指定从请求体读取数据,原有业务逻辑仅需把用到send的地方替换为req.Send即可:
[HttpPost] public async Task<JsonResult> GetVotes([FromBody] GetVotesRequest req) { try { var votes = ctx.Candidates.Where(x => x.Country == req.Send) .OrderByDescending(x => x.Votes) .ToList(); return Json(votes); } catch (Exception ex) { logger.Error(ex); } return Json("foo"); }
方案3:前后端各改一行代码,不需要新增类
- 后端给参数加上
[FromBody]特性:
[HttpPost] public async Task<JsonResult> GetVotes([FromBody] string send)
- 前端不要把参数包成对象,直接传递字符串即可:
$.ajax({ url: '/Countries/GetVotes', type: 'POST', contentType: "application/json", data: JSON.stringify('test'), // 把原来的JSON.stringify(obj)替换为直接序列化字符串 success: function (data) { if (data === null) { // TODO } else { console.log(data); } }, error: function (error) { console.log(error); } });
注意事项
一个控制器方法最多只能有一个参数标记[FromBody],因为请求体的数据流默认只能读取一次,如果有多个参数需要传递,统一封装到复杂模型类里即可。
内容的提问来源于stack exchange,提问作者CrazyLegs
相关产品推荐
相关产品推荐

