Ajax Post提交筛选表单时Controller接收FilterViewModel为空如何解决
问题根因
你遇到的模型为空是两处配置不匹配导致的:
- AJAX请求中你设置了
contentType: "application/json; charset=utf-8",但通过$('form#formfilter').serialize()得到的是application/x-www-form-urlencoded格式的表单字符串,格式不匹配导致[FromBody]无法解析请求体。 - 普通表单提交(点击Submit按钮的场景)无需
[FromBody]注解,MVC会自动从表单域绑定模型;加了[FromBody]后框架只会从请求体读取JSON格式数据解析,和你提交的表单格式不兼容。
解决方案
方案1:改动最小,适配现有表单逻辑
只需要修改两处配置即可:
- 移除Controller参数的
[FromBody]注解:
[HttpPost] public ActionResult Index(FilterViewModel filterViewModel) { // 原有逻辑不变 }
- 删掉AJAX里的
contentType配置,jQuery默认会使用application/x-www-form-urlencoded,刚好适配序列化的表单数据:
$.ajax({ type: "POST", url: "/Overview/Index", data: $('form#formfilter').serialize(), dataType: "json", // 移除原有的contentType配置行 success: function (data) { alert(data.msg); } });
方案2:保留[FromBody],提交JSON格式数据
如果需要保留[FromBody]的写法,需要先把表单数据转换为JSON格式再提交:
- 新增表单转JSON的工具方法:
function serializeFormToJson(formSelector) { const formArray = $(formSelector).serializeArray(); const formObj = {}; $.each(formArray, function () { if (formObj[this.name]) { if (!formObj[this.name].push) formObj[this.name] = [formObj[this.name]]; formObj[this.name].push(this.value || ''); } else { formObj[this.name] = this.value || ''; } }); // 单独处理checkbox的布尔值 $(`${formSelector} input[type=checkbox]`).each(function () { formObj[this.name] = this.checked; }); return JSON.stringify(formObj); }
- 修改AJAX配置:
$.ajax({ type: "POST", url: "/Overview/Index", data: serializeFormToJson('#formfilter'), dataType: "json", contentType: "application/json; charset=utf-8", success: function (data) { alert(data.msg); } });
额外优化
你当前的逻辑仅在勾选复选框时触发请求,如果需要取消勾选时也同步更新筛选结果,移除AJAX外层的if(this.checked)判断即可。
内容的提问来源于stack exchange,提问作者Baneforce
相关产品推荐
相关产品推荐

