MVC Ajax POST请求中ViewModel子对象Pager属性无法绑定如何解决?
问题原因
- 绑定源特性冲突:控制器方法参数同时标注了
[FromBody]和[FromForm],ASP.NET Core 中每个 Action 参数仅能绑定一个来源,同时标注会导致绑定逻辑异常,无法匹配正确的解析规则。 - 数据结构不匹配绑定规则:
[FromBody]基于JSON序列化规则绑定数据,要求嵌套对象以层级结构传递,而你前端提交的是带.的扁平化键名(如Pager.RowsPerPage),不属于标准的JSON嵌套结构,序列化器无法识别为Pager类的属性。 - 实体类属性缺失:
Pager类未定义RowsPerPage属性,即便数据格式正确也无法完成绑定ReportViewModel类未定义StartDate属性,和你代码中读取request.StartDate的逻辑不匹配,属于代码漏写
解决方案
- 统一绑定源特性:根据前端提交的内容类型二选一:
- 若前端提交
application/json格式数据,仅保留[FromBody]特性 - 若前端提交表单格式(
application/x-www-form-urlencoded/multipart/form-data)数据,仅保留[FromForm]特性
- 若前端提交
- 补全实体类缺失属性:
public class ReportViewModel : IEntity, IResponse { // 补全缺失的StartDate属性 public DateTime StartDate { get; set; } public string DateRange { get; set; } // 构造函数中实例化Pager,避免空引用 public ReportViewModel() { Pager = new Pager(); } public Pager Pager { get; set; } } public class Pager { public int CurrentPage { get; set; } // 补全缺失的RowsPerPage属性 public int RowsPerPage { get; set; } }
- 修正前端提交数据格式:
- 若使用
[FromBody]接收JSON,修改为嵌套结构:
- 若使用
{ "StartDate": "2021-11-08T17:25:21.243Z", "Pager": { "RowsPerPage": 1, "CurrentPage": 2 } }
- 若不想修改前端的扁平化键名,改用
[FromForm]接收,前端提交时不要做JSON序列化,直接传递键值对对象,使用默认的表单Content-Type即可,Pager.RowsPerPage这类带点的键名会被[FromForm]自动解析为嵌套对象属性。
内容的提问来源于stack exchange,提问作者Jake Manet
相关产品推荐
相关产品推荐

