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

如何在ASP.NET MVC控制器中获取动态修改的boughtQuantity值?

如何在ASP.NET MVC的SaleController中获取动态修改的boughtQuantity值?

问题现状

在ASP.NET MVC的SaleController中尝试获取boughtQuantity属性时,始终返回0。该值通过JavaScript动态修改数量后,尝试通过innerText传递到隐藏字段,无论是用localStorage还是Request.Form都无法成功获取正确值。

核心问题分析

视图代码(Cart.cshtml)的问题

  1. 隐藏字段不在提交表单内:用于传递数量的隐藏字段<input type="hidden" id="sentQuantity" name="boughtQuantity">是独立表单,不在触发提交的Buy表单中,导致提交时不会携带这个参数。
  2. 重复ID导致元素冲突:循环渲染多个商品时,increase、decrease、quantity、sentQuantity这些ID会重复,JavaScript只能操作第一个匹配的元素,无法正确对应每个商品。
  3. 错误设置input值:修改隐藏字段时用了innerText,但input元素的有效值应该通过value属性设置,而非innerText。
  4. 数量状态未独立维护: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:35:37