You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:20:57