如何通过jQuery将含OrderDetail的表单数据传递至.NET API
问题:如何通过jQuery将包含集合的表单数据正确传递到.NET API?
我创建了一个简单Web项目,希望通过jQuery将HTML中的数据传递至.NET API。首先定义了如下模型类:
public class Order { public string Name { get; set; } = string.Empty; public string OrderCode { get; set; } = string.Empty; public string OrderAddress { get; set; } = string.Empty; public ICollection<OrderDetail> OrderDetail { get; set; } = new List<OrderDetail>(); } public class OrderDetail { public string ProductCode { get; set; } = string.Empty; public int Qty { get; set; } }
在ApiController中创建了如下方法:
[HttpPost("postorder1")] public IActionResult PostOrder1 ([FromForm] Order order) { Console.WriteLine(JsonSerializer.Serialize(order, Defaults.DefaultJsonSerializerOption)); return Ok(); }
视图代码如下:
@model Order <form id="orderform_passquery"> <label asp-for="OrderCode"></label> <input asp-for="OrderCode" type="text" class="form-control" /> <label asp-for="Name"></label> <input asp-for="Name" type="text" class="form-control" /> <label asp-for="OrderAddress"></label> <textarea asp-for="OrderAddress" class="form-control"></textarea> <table id="orderdetail"> <thead> <tr> <th>Product Code</th> <th>Qty</th> </tr> </thead> <tbody> <tr> <td data-column="productcode">Item One</td> <td data-column="qty">123</td> </tr> </tbody> </table> <div class="mt-1"> <button id="cmdSubmit" class="btn btn-primary">Submit</button> </div> </form>
JavaScript函数如下:
function OnSubmit() { var url = "api/data/postorder1"; var orderTableId = "orderdetail"; var formPassqueryId = "orderform_passquery"; const formElement = document.getElementById(formPassqueryId); var formData = new FormData(formElement); const table = document.getElementById(orderTableId); var tableData = []; const tableRows = table.querySelectorAll("tbody tr"); tableRows.forEach(function (row) { let productCode = row.querySelector('td[data-column="productcode"]').textContent; let qty = row.querySelector('td[data-column="qty"]').textContent; tableData.push({ productCode, qty }); }); formData.append("orderDetail", JSON.stringify(tableData)); const postData = new URLSearchParams(formData); fetch(url, { method: "POST", body: postData }).then(response => { if (response.ok) { return response.text() } return response.text() .then(text => { throw new Error(text) }) } ) }
运行项目并提交数据后,Order主数据能正常接收,但OrderDetail始终为空。已调试确认JavaScript中tableData存在数据,请问如何正确传递OrderDetail数据?
解决方案
问题核心是**[FromForm]模型绑定对集合数据的格式要求**:.NET无法直接解析你传入的JSON字符串,它期望集合数据以OrderDetail[索引].属性名的键值对形式传递。以下两种方案可解决问题:
方案一:保持[FromForm],调整JS数据格式
修改JavaScript代码,将表格数据拆解为符合FormData集合格式的键值对,而非传递JSON字符串:
function OnSubmit() { var url = "api/data/postorder1"; var orderTableId = "orderdetail"; var formPassqueryId = "orderform_passquery"; const formElement = document.getElementById(formPassqueryId); var formData = new FormData(formElement); const table = document.getElementById(orderTableId); const tableRows = table.querySelectorAll("tbody tr"); // 循环表格行,按.NET要求的格式添加集合数据 tableRows.forEach(function (row, index) { let productCode = row.querySelector('td[data-column="productcode"]').textContent; let qty = parseInt(row.querySelector('td[data-column="qty"]').textContent); // 转成数字匹配int类型 // 按索引命名键,让模型绑定识别集合 formData.append(`OrderDetail[${index}].ProductCode`, productCode); formData.append(`OrderDetail[${index}].Qty`, qty); }); const postData = new URLSearchParams(formData); fetch(url, { method: "POST", body: postData }).then(response => { if (response.ok) { return response.text() } return response.text() .then(text => { throw new Error(text) }) }) }
方案二:改用JSON格式传递(推荐)
对于包含集合的复杂对象,JSON格式传递更简洁,只需修改API控制器的接收方式和JS代码:
1. 修改API控制器方法
将[FromForm]改为[FromBody],让.NET解析JSON格式的请求体:
[HttpPost("postorder1")] public IActionResult PostOrder1 ([FromBody] Order order) { Console.WriteLine(JsonSerializer.Serialize(order, Defaults.DefaultJsonSerializerOption)); return Ok(); }
2. 修改JavaScript代码
直接构建完整的Order对象,转成JSON字符串传递,并设置正确的请求头:
function OnSubmit() { var url = "api/data/postorder1"; var orderTableId = "orderdetail"; var formPassqueryId = "orderform_passquery"; const formElement = document.getElementById(formPassqueryId); // 从表单获取主数据 const formData = new FormData(formElement); const order = { OrderCode: formData.get('OrderCode'), Name: formData.get('Name'), OrderAddress: formData.get('OrderAddress'), OrderDetail: [] }; // 处理表格数据,注意属性名和C#模型一致 const table = document.getElementById(orderTableId); const tableRows = table.querySelectorAll("tbody tr"); tableRows.forEach(function (row) { let productCode = row.querySelector('td[data-column="productcode"]').textContent; let qty = parseInt(row.querySelector('td[data-column="qty"]').textContent); order.OrderDetail.push({ ProductCode: productCode, Qty: qty }); }); fetch(url, { method: "POST", headers: { 'Content-Type': 'application/json' // 必须指定JSON类型的请求头 }, body: JSON.stringify(order) }).then(response => { if (response.ok) { return response.text() } return response.text() .then(text => { throw new Error(text) }) }) }
内容的提问来源于stack exchange,提问作者Carrie Kaski
相关产品推荐
相关产品推荐

