如何用jQuery Ajax向.NET Core 6 MVC控制器提交多个对象
多对象表单提交故障排查
问题背景
实现携带多个对象提交表单功能时,长期排查未定位代码故障点,需指出代码疏漏。
现有实现代码
前端脚本
function getInvoiceObject() { var Invoice = new Object(); Invoice.InvoiceId = $('#InvoiceId').val(); Invoice.InvoiceTemplateId = $('#InvoiceTemplateId').val(); Invoice.InvoiceDueAfterDays = $('#InvoiceDueAfterDays').val(); Invoice.DefulatTerms = $('#DefulatTerms').val(); Invoice.DefaultFooter = $('#DefaultFooter').val(); return Invoice; } function getEmailObject() { var Email = new Object(); Email.EmailId = $('#EmailId').val(); Email.InvoiceEmailBody = $('#InvoiceEmailBody').val(); Email.OverDueInvoiceEmailBody = $('#OverDueInvoiceEmailBody').val(); return Email; } function SaveAllSettings() { debugger; var InvoicesVM = getInvoiceObject(); var EmailVM = getEmailObject(); var AllSettings = {InvoicesVM:InvoicesVM, EmailVM: EmailVM}; $.ajax({ type: 'POST', url: "/Settings/SaveAllSettings", data: '{ "AllSettings":' + JSON.stringify(AllSettings) + '}', processData: false, traditional: true, cache: false, contentType: "application/json; charset=utf-8", dataType: "json", success: function (response) { toastr.success('Saved SuccessFully!'); }, error: function (msg) { //toastr.error('Cannot Save the Data!'); } }) }
后端控制器代码
[HttpPost] public JsonResult SaveAllSettings(SettingsVM AllSettings) { return Json(""); }
ViewModel定义
public class SettingsVM { public InvoiceSettingsVM InvoicesVM { get; set; } public EmailSettingsVM EmailVM { get; set; } }
代码疏漏点
- 请求体JSON结构多嵌套一层:当前AJAX提交的JSON根节点是
AllSettings,但ASP.NET模型绑定会直接将请求体根节点和接口参数SettingsVM AllSettings做匹配,多余的外层包裹会导致所有属性绑定为null。 - 接口参数缺少绑定源特性:当请求
contentType为application/json时,必须给参数加[FromBody]特性,否则框架默认从表单字段取值,无法解析JSON请求体。 - 属性拼写不一致:前端发票对象中写的是
DefulatTerms,和常规命名的DefaultTerms拼写不匹配,会导致该字段始终绑定失败。 - 冗余配置干扰传参:
processData: false、traditional: true是为FormData、表单序列化传参设计的配置,在JSON传参场景下属于冗余配置,可能引发请求解析异常。 - 值类型隐式转换风险:jQuery的
.val()方法取到的值均为字符串类型,若后端InvoiceDueAfterDays等字段是数值、日期类型,未做显式转换会触发类型不匹配的绑定错误。
修正方案
- 调整前端AJAX传参逻辑,去掉多余的JSON外层包裹,删除冗余配置,修正拼写和类型转换问题:
function SaveAllSettings() { var InvoicesVM = getInvoiceObject(); var EmailVM = getEmailObject(); // 修正拼写错误 InvoicesVM.DefaultTerms = $('#DefulatTerms').val(); // 数值类型显式转换 InvoicesVM.InvoiceDueAfterDays = Number($('#InvoiceDueAfterDays').val()); var AllSettings = {InvoicesVM:InvoicesVM, EmailVM: EmailVM}; $.ajax({ type: 'POST', url: "/Settings/SaveAllSettings", data: JSON.stringify(AllSettings), cache: false, contentType: "application/json; charset=utf-8", dataType: "json", success: function (response) { toastr.success('保存成功!'); }, error: function (msg) { toastr.error('保存失败,请重试!'); } }) }
- 给后端接口参数添加
[FromBody]特性:
[HttpPost] public JsonResult SaveAllSettings([FromBody] SettingsVM AllSettings) { return Json(new { success = true }); }
- 统一前后端属性名拼写,确保前端JS对象的属性名和C# ViewModel的属性名完全一致(ASP.NET模型绑定对属性名大小写不敏感,但拼写必须完全匹配)。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

