【问题标题】:MVC 5 drop down list value not passing into controllerMVC 5下拉列表值未传递到控制器
【发布时间】:2018-05-02 16:47:50
【问题描述】:

我在我的产品详细信息视图中创建了一个下拉列表,它有 5 个硬编码值 (1,2,3,4,5),当我选择想要的值时,我将其传递给ShoppingCart 控制器,然后当我单击添加到购物车按钮时进入购物车模型的同名方法,但是当我将商品添加到购物车时,数量显示为 0。

我的产品详情视图:

@model BigVisionGames.Models.Products

@{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h3>Product:  @Model.ProductName</h3>

<div id="product-details">
<p>
    <em>Price: </em>
    £@($"{Model.Price:F}")
</p>

<div style="color:black">
    @Html.DropDownListFor(model => model.ChosenQuantity, new 
List<SelectListItem>
 {
            new SelectListItem{ Text="1", Value = "1" },
            new SelectListItem{ Text="2", Value = "2" },
            new SelectListItem{ Text="3", Value = "3" },
            new SelectListItem{ Text="4", Value = "4" },
            new SelectListItem{ Text="5", Value = "5" }
        })

    @Html.ValidationMessageFor(model => model.ChosenQuantity, "", new { @class = "text-danger" })
</div>

@if (Model.StockLevel == 0)
{
    <p style="color:red">This item is currently out of stock!</p>
}
else
{
    <p class="btn">
        @Html.ActionLink("Add to cart", "AddToCartWithQuantity", "ShoppingCart", new { id = Model.Id}, "")
    </p>
}

ShoppingCartController 方法

        public ActionResult AddToCartWithQuantity(int id, Products productModel)

    {

        // Retrieve the product from the database
        var addedproduct = storeDB.Products
            .Single(product => product.Id == id);

        // Add it to the shopping cart
        var cart = ShoppingCart.GetCart(this.HttpContext);

        cart.AddToCartWithQuantity(addedproduct, productModel.ChosenQuantity);

        // Go back to the main store page for more shopping
        return RedirectToAction("Index");
    }

ShoppingCart Model 设置所选数量的方法

public void AddToCartWithQuantity(Products product, int chosenQuantity)
    {
        // Get the matching cart and product instances
        var cartItem = storeDB.Carts.SingleOrDefault(
            c => c.CartId == ShoppingCartId
                 && c.ProductId == product.Id);

        if (cartItem == null)
        {
            // Create a new cart item if no cart item exists
            cartItem = new Cart
            {
                ProductId = product.Id,
                CartId = ShoppingCartId,
                Quantity = chosenQuantity,
                DateCreated = DateTime.Now
            };
            storeDB.Carts.Add(cartItem);
        }
        else
        {
            // If the item does exist in the cart, 
            // then add one to the quantity
            cartItem.Quantity++;
        }

        // Save changes
        storeDB.SaveChanges();
    }

【问题讨论】:

  • 您当前的代码不能满足您的要求。它呈现一个锚标记。您需要提交表单或 ajax 发布或发送到操作方法。
  • 你的表格在哪里?

标签: c# asp.net-mvc


【解决方案1】:

您当前的代码正在呈现一个锚标记并单击它将使用查询字符串中的 id 执行 GET 请求。如果您想从数量下拉列表中发送选择的值,您需要阅读并发送它。

首先更新您呈现链接的代码,以便它为a 标记创建一个Id 属性,我们稍后可以在javascript 中使用它来覆盖默认的点击行为。

@Html.ActionLink("Add to cart", "AddToCartWithQuantity", "ShoppingCart",
                                  new { id = Model.Id },new { id = "addToCart" } )

这将呈现带有 id addToCart 的锚标记

现在您可以使用一些 javascript 来侦听此锚标记上的点击事件,防止默认行为(导航到目标 url)并发送我们想要的数据。这是一个做ajax帖子的例子

$(function (){

    $("#addToCart").click(function (e){
        e.preventDefault();
        var url = $(this).attr("href");
        url = url + '?chosenQuantity=' + $("#ChosenQuantity").val();
        $.post(url).done(function (res){
            if (res.status === "success")
            {
                //update cart UI
                alert(res.cartItemCount);
            }
        });

    });

});

现在我们正在执行 ajax 提交,让我们返回一个带有状态和 cartItemCount 属性的 JSON 响应。我们的 js 代码正在检查这个以查看在 ajax 调用 done 事件中操作是否成功。此外,由于我们只需要 Id 和数量,因此您不需要使用 Product 实体作为参数。对Id 使用简单的int 类型

[HttpPost]
public ActionResult AddToCartWithQuantity(int id, int chosenQuantity)
{
    // Your existing code to save. Use id to get the product
    // to do  :replace the hard coded 1 with actual value from db
    return Json(new { status = "success", cartItemCount = 1 });
}

另一种选择是提交表单。在这种情况下,将您的 SELECT 和链接包装在表单元素中(将其操作设置为 /ShoppingCart/AddToCartWithQuantity)并在单击链接时提交表单。

<form action='@Url.Action("AddToCartWithQuantity","ShoppingCart")' method='post'>
  <!-- SELECT and Link goes here-->
</form>

脚本将是

$(function (){

    $("#addToCart").click(function (e){
        e.preventDefault();
        $(this).closest("form").submit();    
    });

});

由于我们的代码正在执行完整的表单提交,因此请确保您的操作方法返回重定向结果。

[HttpPost]
public ActionResult AddToCartWithQuantity(NewProjectModel product, int chosenQuantity)
{
    // Your existing code to save
    return RedirectToAction("Index","ShoppingCart");
}

【讨论】:

  • 查看ActionResult AddToCartWithQuantity,是来自ShoppingCartController 的方法吗?而且我有点困惑我必须从所述方法中删除和保留什么,例如将 JSON 响应放在哪里。
  • 我没有意识到你有 2. 发布到你想要的方法。如果您要发布到具有 return RedirectToAction("Index"); 语句的那个​​,请做一个表单发布(答案中的第二种方法),如果您要发布到另一个,请使用 ajax 方法
  • 我将尝试提交表单,我对您将我的选择和链接包装在表单元素中的意思感到困惑,我在哪里放置该表单操作以及其中的内容?跨度>
  • 对于提交表单,您的输入元素应该在表单内。请参阅我在答案中的代码。将 &lt;!-- SELECT and Link goes here--&gt; 替换为呈现链接和 SELECT 的现有代码
  • 我不确定 Select 和 Link 是什么意思,我必须把它放在表单操作中吗? @Html.ActionLink("加入购物车", "AddToCartWithQuantity", "ShoppingCart", new { id = Model.Id}, "")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多