ASP.NET Core 6 MVC添加购物车始终返回首个商品问题求助
问题原因
- 所有商品共享同一个
<form>标签,asp-for生成的表单控件(如Name、Price)会拥有相同的name属性。提交表单时,浏览器会发送所有同名控件的值,模型绑定仅能识别其中一个值,导致控制器无法正确匹配点击的商品。 - 控制器通过
Name、Price、Discription查询商品ID的逻辑存在风险:若存在信息完全一致的商品,会错误获取首个商品的ID,且查询效率低下。
解决方案
1. 重构控制器代码
直接接收商品ID和购买数量,跳过通过商品信息匹配ID的环节,提升准确性和效率:
public IActionResult AddToBasket(int productId, int amount) { if (AuthController.user != null) { using Data data = new Data(); // 验证商品是否存在(可选,避免无效ID) var targetProduct = data.products.Find(productId); if (targetProduct == null) { return RedirectToAction("Products"); } data.basket.Add(new BasketModel { Amount = amount, AccountId = AuthController.user.Id, ProductId = productId }); data.SaveChanges(); return RedirectToAction("Products"); } // 用户未登录的跳转逻辑 return RedirectToAction("Login", "Auth"); }
2. 修改视图代码
为每个商品单独创建<form>,通过隐藏字段传递商品ID,确保提交时仅发送当前商品的信息:
@foreach(ProductsModel pro in ViewBag.prod) { <div class="col-lg-4 col-sm-12" style="float:right;"> <div class="beds_section active"> <form method="post" asp-action="AddToBasket" asp-controller="Products" style="width:100%;"> <!-- 隐藏字段传递商品ID --> <input type="hidden" value="@pro.Id" name="productId" /> <input readonly="readonly" class="bed_text" value="@pro.Name" style="border:none;" /> <div><img src="../@pro.Img" class="image_2"></div> <input type="number" placeholder="amount" name="amount" value="1" min="1" max="@pro.Amount" style="width:80px;float:right;" /> <span class="text-danger"></span> <input style="border:none; width:150px;" readonly="readonly" value="@pro.Price" /> <br /> <br /> <input style="border:none; width:100%; height:100%;" readonly="readonly" value="@pro.Discription" /> <input type="submit" value="Add to Basket" style="float:right;" /> </form> </div> </div> }
额外优化建议
- 避免直接调用
AuthController.user,建议使用ASP.NET Core内置的User对象或依赖注入获取当前登录用户信息,符合身份验证最佳实践。 - 可以创建
AddToBasketViewModel并添加数据注解(如[Required]、[Range(1, int.MaxValue)]),结合视图的asp-validation-for实现前端验证,提升用户体验。
内容的提问来源于stack exchange,提问作者Mohammed.K
相关产品推荐
相关产品推荐

