【问题标题】:ASP.NET MVC doesn't pass on id when I select it当我选择它时,ASP.NET MVC 不传递 id
【发布时间】:2016-07-15 14:26:03
【问题描述】:

我正在创建一个基本的网上商店来学习如何使用 C# 编程。我是初学者,我在电子书、youtube 和 Stackoverflow 的帮助下学习一切。现在我遇到了一个我自己无法解决的问题,所以我真的需要你们的帮助。

问题如下.. 当我按下菜单中的“网上商店”按钮时,我会转到一个页面,该页面列出了我所有的产品,包括名称、图片、价格等,还有一个“添加到购物车”按钮。当我按下此按钮时,我应该进入我的购物车,我应该看到所选数量的所选产品(此时默认为 1)和产品价格以及所有产品的总价格。当我按下按钮时,我去了我的购物车,但这个购物车仍然是空的。在 de CartController 中发送到我的 AddToCart 方法的 id 为空......我该如何解决这个问题?大家可以看看下面的相关代码。

路由配置

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace Webshop
{
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
}

ProductSummary(具有 AddToCart 按钮的部分视图)

@model Webshop.Models.Entiteiten.Product

<div class="col-md-4">
    @if (@Model.ImageData != null)
        {
    <div class="pull-left" style="margin-right: 10px">
        <img class="img-thumbnail" width="75" height="75"
             src="@Url.Action("GetImage", "Product",new { @Model.ProductID })" />
    </div>
}
<h3>@Model.Name</h3>
@Model.Description
<h4>@Model.Price.ToString("c")</h4>
@using (Html.BeginForm("AddToCart", "Cart"))
        {
    <div class="pull-right">
        @Html.HiddenFor(x => x.ProductID)
        @Html.Hidden("returnUrl", Request.Url.PathAndQuery)
        <input type="submit" class="btn btn-success" value="Add to cart" />
    </div>
}

购物车模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Webshop.Models.Entiteiten
{
    public class Cart
{
    private List<CartLine> lineCollection = new List<CartLine>();

    public void AddItem(Product product, int quantity)
    {
        CartLine line = lineCollection
        .Where(p => p.Product.ProductID == product.ProductID)
        .FirstOrDefault();
        if (line == null)
        {
            lineCollection.Add(new CartLine
            {
                Product = product,
                Quantity = quantity
            });
        }
        else {
            line.Quantity += quantity;
        }
    }
    public void RemoveLine(Product product)
    {
        lineCollection.RemoveAll(l => l.Product.ProductID ==
        product.ProductID);
    }
    public decimal ComputeTotalValue()
    {
        return lineCollection.Sum(e => e.Product.Price * e.Quantity);
    }
    public void Clear()
    {
        lineCollection.Clear();
    }
    public IEnumerable<CartLine> Lines
    {
        get { return lineCollection; }
    }
}
public class CartLine
{
    public Product Product { get; set; }
    public int Quantity { get; set; }
}
}

CartController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Webshop.DB.Abstract;
using Webshop.Models.Entiteiten;
using Webshop.Models;

namespace Webshop.Controllers
{
public class CartController : Controller
{
    private IProductRepository repository;
    public CartController(IProductRepository repo)
    {
        repository = repo;
    }

    public ViewResult Index(string returnUrl)
    {
        return View(new CartIndexViewModel
        {
            Cart = GetCart(),
            ReturnUrl = returnUrl
        });
    }

    public RedirectToRouteResult AddToCart(int? id, string returnUrl)
    {
        Product product = repository.Products
        .FirstOrDefault(p => p.ProductID == id);
        if (product != null)
        {
            GetCart().AddItem(product, 1);
        }
        return RedirectToAction("Index", new { returnUrl });
    }

    public RedirectToRouteResult RemoveFromCart(int? id, string returnUrl)
    {
        Product product = repository.Products
        .FirstOrDefault(p => p.ProductID == id);
        if (product != null)
        {
            GetCart().RemoveLine(product);
        }
        return RedirectToAction("Index", new { returnUrl });
    }

    private Cart GetCart()
    {
        Cart cart = (Cart)Session["Cart"];
        if (cart == null)
        {
            cart = new Cart();
            Session["Cart"] = cart;
        }
        return cart;
    }
}
}

CartIndexViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Webshop.Models.Entiteiten;

namespace Webshop.Models
{
    public class CartIndexViewModel
    {
        public Cart Cart { get; set; }
        public string ReturnUrl { get; set; }
    }
}

提前谢谢各位!

【问题讨论】:

    标签: c# asp.net asp.net-mvc


    【解决方案1】:

    这可能是因为您发布的值与控制器操作所期望的参数名称不匹配。如果您查看现有表单,您会发现您发布了一个名为 ProductID 的值到您的 Cart/AddToCart 控制器操作:

    <!-- This will post a value named "ProductID" to Cart/AddToCart -->
    @Html.HiddenFor(x => x.ProductID)
    

    但是,如果您查看操作本身,它需要一个名为 id 的参数:

    public RedirectToRouteResult AddToCart(int? id, string returnUrl)
    {
        // Omitted for brevity
    }
    

    发生这种情况的原因是HiddenFor() 助手将创建一个具有name 属性的元素,该属性对应于传入的属性名称:

    <input id='ProductID' name='ProductID' type='hidden' value='{your-product-id}' />
    

    发布后,您的 AddToCart 控制器操作看不到名为 ProductID 的参数,因此它不知道如何映射它(因为只有 id 存在)。

    可能的解决方案

    有几种可能的方法可以解决这个问题,具体取决于您的偏好。

    将您的 AddToCart 参数名称从 id 重命名为 ProductID

    public RedirectToRouteResult AddToCart(int? ProductID, string returnUrl)
    {
         // Omitted for brevity
    }
    

    将表单中的属性从 ProductID 重命名为 id 以匹配您的操作

    @Html.Hidden("id", Model.ProductID)
    

    【讨论】:

    • 我做了第二个解决方案,效果很好。非常感谢,你无法相信我在这个问题上被困了多少小时。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 2016-02-21
    • 1970-01-01
    相关资源
    最近更新 更多