订单保存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
相关产品推荐
相关产品推荐

