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

订单保存JSON无法命中控制器,无报错仅提示未完成求助

订单保存请求参数绑定失败问题排查与修复

核心问题分析

你收到Error: Order Not Complete!说明控制器已经被命中,但name/address/order参数全部为null,导致无法进入业务逻辑分支。根源在于ASP.NET无法直接通过[FromBody]绑定多个独立参数(请求体只能被解析一次),同时存在JSON字段名与C#属性名的大小写不匹配问题。

修复步骤

1. 创建统一的请求ViewModel

新建一个用于接收订单提交数据的ViewModel类,将所有参数封装到一个对象中:

public class OrderSubmitViewModel
{
    public string Name { get; set; }
    public string Address { get; set; }
    public Order[] Order { get; set; }
}

// 确保Order类属性与JSON字段映射正确,可添加JsonPropertyName特性
public class Order
{
    public Guid OrderId { get; set; }
    [JsonPropertyName("productName")]
    public string ProductName { get; set; }
    [JsonPropertyName("quantity")]
    public int Quantity { get; set; }
    [JsonPropertyName("price")]
    public decimal Price { get; set; }
    [JsonPropertyName("amount")]
    public decimal Amount { get; set; }
    public Guid CustomerId { get; set; }
}

2. 修改控制器Action参数

将原Action的多个参数替换为ViewModel,并使用[FromBody]绑定整个对象:

public ActionResult SaveOrder([FromBody] OrderSubmitViewModel model)
{
    string result = "Error! Your Order Is Not Complete!";
    try
    {
        // 检查ViewModel及内部属性是否有效
        if (model != null && !string.IsNullOrEmpty(model.Name) && 
            !string.IsNullOrEmpty(model.Address) && model.Order != null && model.Order.Length > 0)
        {
            var customerId = Guid.NewGuid();
            Customer customerModel = new();
            customerModel.CustomerId = customerId;
            customerModel.Name = model.Name;
            customerModel.Address = model.Address;
            customerModel.OrderDate = DateTime.Now;
            db.Customers.Add(customerModel);

            foreach (var item in model.Order)
            {
                var orderId = Guid.NewGuid();
                Order orderModel = new();
                orderModel.OrderId = orderId;
                orderModel.ProductName = item.ProductName;
                orderModel.Quantity = item.Quantity;
                orderModel.Price = item.Price;
                orderModel.Amount = item.Amount;
                orderModel.CustomerId = customerId;
                db.Orders.Add(orderModel);
            }
            db.SaveChanges();
            result = "Successfully! Order Is Complete!";
        }
        return Json(result);
    }
    catch (Exception ex)
    {
        // 捕获异常并返回具体错误信息,而非直接抛出
        return Json($"Error: {ex.Message}");
    }
}

3. 可选:全局配置JSON序列化驼峰命名

如果不想给每个属性加JsonPropertyName,可以在Startup/Program.cs中配置全局JSON序列化规则,自动映射小驼峰JSON字段到大驼峰C#属性:

// ASP.NET Core 6+ Program.cs
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    });

4. 修正JavaScript数据类型转换

从DOM获取的数值类数据(数量、价格、金额)是字符串类型,需要转为对应数值类型,避免C#端类型转换失败导致参数绑定为空:

$.each($("#detailsTable tbody tr"), function () {
    orderArr.push({
        productName : $(this).find('td:eq(0)').html(),
        quantity    : parseInt($(this).find('td:eq(1)').html()), // 转为整数
        price       : parseFloat($(this).find('td:eq(2)').html()), // 转为浮点数
        amount      : parseFloat($(this).find('td:eq(3)').html())
    });
});

关键说明

  • ASP.NET中[FromBody]只能用于一个参数,因为请求体流只能被读取一次,多个独立参数无法被正确绑定。
  • JSON字段名与C#属性名的大小写必须匹配,通过特性或全局配置解决映射问题。
  • 从DOM获取的数值类数据需要手动转换类型,否则会因类型不匹配导致参数绑定失败。

内容的提问来源于stack exchange,提问作者Majid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:48:43