如何在ASP.NET MVC控制器中获取动态修改的boughtQuantity值?
如何在ASP.NET MVC的SaleController中获取动态修改的boughtQuantity值?
问题现状
在ASP.NET MVC的SaleController中尝试获取boughtQuantity属性时,始终返回0。该值通过JavaScript动态修改数量后,尝试通过innerText传递到隐藏字段,无论是用localStorage还是Request.Form都无法成功获取正确值。
核心问题分析
视图代码(Cart.cshtml)的问题
- 隐藏字段不在提交表单内:用于传递数量的隐藏字段
<input type="hidden" id="sentQuantity" name="boughtQuantity">是独立表单,不在触发提交的Buy表单中,导致提交时不会携带这个参数。 - 重复ID导致元素冲突:循环渲染多个商品时,
increase、decrease、quantity、sentQuantity这些ID会重复,JavaScript只能操作第一个匹配的元素,无法正确对应每个商品。 - 错误设置input值:修改隐藏字段时用了
innerText,但input元素的有效值应该通过value属性设置,而非innerText。 - 数量状态未独立维护:JavaScript中全局维护
boughtQuantity,无法区分多个商品的不同数量值。
控制器代码(SaleController.cs)的问题
Buy方法尝试通过Request.Form["boughtQuantity"]获取值,但由于字段不在提交表单中,自然无法获取到正确数据。
修复步骤
1. 修改Cart.cshtml视图
调整表单结构与元素标识
将隐藏字段移到Buy表单内部,给每个商品的元素添加唯一前缀(基于商品ID),确保每个商品的操作独立:
@foreach(var item in Model) { <tr> <!-- 其他列保持不变 --> <td> <button id="increase-@item.Id" type="button" class="btn btn-primary increase-btn" data-product-id="@item.Id"> <span class="fa fa-plus" style="color:white"></span> </button> <span id="quantity-@item.Id" class="quantity-display">1</span> <button id="decrease-@item.Id" type="button" class="btn btn-primary decrease-btn" data-product-id="@item.Id"> <span class="fa fa-minus" style="color:white"></span> </button> </td> <td> <form asp-action="Buy" asp-route-id="@item.Id" onclick="return confirm('Are you sure you want to buy this product?');"> <input type="hidden" name="boughtQuantity" id="sentQuantity-@item.Id" value="1"> <input id="buyButton-@item.Id" type="submit" value="Buy" class="btn btn-success"/> </form> </td> <!-- 其他列保持不变 --> </tr> }
同时给库存数量的td添加唯一ID:
<td id="totalQuantity-@item.Id"> @Html.DisplayFor(model => item.StockQuantity) </td>
更新JavaScript逻辑
修改脚本,让每个商品的数量独立控制,绑定事件时传递商品ID,正确设置隐藏字段的value:
@section scripts{ <script type="text/javascript"> // 为每个商品绑定增加数量事件 document.querySelectorAll('.increase-btn').forEach(btn => { btn.addEventListener('click', function() { const productId = this.dataset.productId; const quantityElement = document.getElementById(`quantity-${productId}`); const sentQuantityElement = document.getElementById(`sentQuantity-${productId}`); const totalQuantityElement = document.getElementById(`totalQuantity-${productId}`); let currentQuantity = parseInt(quantityElement.textContent); const maxQuantity = parseInt(totalQuantityElement.textContent); if(currentQuantity < maxQuantity) { currentQuantity++; quantityElement.textContent = currentQuantity; sentQuantityElement.value = currentQuantity; } }); }); // 为每个商品绑定减少数量事件 document.querySelectorAll('.decrease-btn').forEach(btn => { btn.addEventListener('click', function() { const productId = this.dataset.productId; const quantityElement = document.getElementById(`quantity-${productId}`); const sentQuantityElement = document.getElementById(`sentQuantity-${productId}`); let currentQuantity = parseInt(quantityElement.textContent); if(currentQuantity > 1) { // 至少保留1件商品 currentQuantity--; quantityElement.textContent = currentQuantity; sentQuantityElement.value = currentQuantity; } }); }); </script> }
2. 修改SaleController.cs的Buy方法
直接通过参数绑定接收boughtQuantity,无需手动读取Request.Form,同时增加数量合法性校验:
[HttpPost] public IActionResult Buy(int id, int boughtQuantity) { var bought = _context.Products.Find(id); if(bought == null) { return RedirectToAction(nameof(EmptyCart)); } // 验证购买数量不超过库存且不少于1 if(boughtQuantity > bought.StockQuantity || boughtQuantity < 1) { ModelState.AddModelError("", "Invalid purchase quantity"); var productsInCart = new List<Product> { bought }; return View("Cart", productsInCart); } Sale newSale = new Sale(); newSale.SaleDate = DateTime.UtcNow; newSale.ProductId = bought.Id; newSale.ProductQuantity = boughtQuantity; var saleWeight = bought.Weight * boughtQuantity; var lightShippingCost = CalculateShippingCost(5,50); var heavyShippingCost = CalculateShippingCost(50,100); newSale.TotalValue = ((boughtQuantity) * (bought.Price)) + Convert.ToDecimal(saleWeight < 15 ? lightShippingCost : heavyShippingCost); newSale.Status = SaleStatusEnum.AwaitingPayment; if(ModelState.IsValid) { _context.Sales.Add(newSale); // 更新商品库存 bought.StockQuantity -= boughtQuantity; _context.SaveChanges(); return View(newSale); } var products = new List<Product> { bought }; return View("Cart", products); }
关键说明
- 提交表单必须包含需要传递的字段,这是控制器能接收参数的前提。
- 循环渲染元素时必须使用唯一标识,避免DOM元素冲突。
- input元素的值通过
value属性设置,而非innerText。 - 控制器优先使用参数绑定,代码更简洁且不易出错。
内容的提问来源于stack exchange,提问作者LucasRBA
相关产品推荐
相关产品推荐

