1

My question is when I click actionlink,the view send specific ID to controller(ex. ProductID = 6), but my controller grab all data to me not specific ID data.

I think the problem is the lambda expression at controller, it will grab all data to me.

These are my Models:

    public class ShoppingCart
    {
        public List<ShoppingCartItemModel> items = new List<ShoppingCartItemModel>();

        public IEnumerable<ShoppingCartItemModel> Items 
        {
            get { return items; }
        }
    }


    public class ShoppingCartItemModel
    {
        public Product Product
        {
            get;
            set;
        }

        public int Quantity { get; set; }
    }

Controller :

        [HttpGet]
        public ActionResult EditFromCart(int ProductID)
        {

            ShoppingCart cart = GetCart();
            cart.items.Where(r => r.Product.ProductID == ProductID)
                      .Select(r => new  ShoppingCartItemModel
                                        {
                                            Product = r.Product,
                                            Quantity = r.Quantity
                                        });

            return View(cart);

            //return RedirectToAction("Index", "ShoppingCart");
        }


        private ShoppingCart GetCart()
        {
            ShoppingCart cart = (ShoppingCart)Session["Cart"];

            //如果現有購物車中已經沒有任何內容
            if (cart == null)
            {
                //產生新購物車物件
                cart = new ShoppingCart();

                //用session保存此購物車物件
                Session["Cart"] = cart;
            }

            //如果現有購物車中已經有內容,就傳回 view 顯示
            return cart;
        }

View

@model ShoppingCart

@{
    ViewBag.Title = "購物車內容";
}

<h2>Index</h2>

<table class="table">
    <thead>
        <tr>
            <th>
                Quantity
            </th>
            <th>
                Item
            </th>
            <th class="text-right">
                Price
            </th>
            <th class="text-right">
                Subtotal
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.items)
        {
            <tr>
                <td class="text-center">
                    @item.Quantity
                </td>
                <td class="text-center">
                    @item.Product.ProductName
                </td>
                <td class="text-center">
                    @item.Product.Price.ToString("c")
                </td>
                <td class="text-center">
                    @( (item.Quantity * item.Product.Price).ToString("c"))
                </td>
                <td>
                    @using (Html.BeginForm("RemoveFromCart", "ShoppingCart"))
                    {
                        @Html.Hidden("ProductId", item.Product.ProductID)
                        @*@Html.HiddenFor(x => x.ReturnUrl)*@
                        <input class="btn btn-warning" type="submit" value="Remove">
                    }
                </td>
                <td>
                    @using (Html.BeginForm("EditFromCart", "ShoppingCart", FormMethod.Get))
                    {
                        @Html.Hidden("ProductId", item.Product.ProductID)
                        <input class="btn btn-warning" type="submit" value="Edit">
                    }
                </td>

            </tr>
        }
    </tbody>

</table>
1
  • you are passing entire cart value to view Commented Sep 29, 2016 at 7:22

3 Answers 3

2

The key issue is that this code doesn't return the result of the LINQ queries, because you have not assigned a variable to the result:

cart.items.Where(r => r.Product.ProductID == ProductID)
                      .Select(r => new  ShoppingCartItemModel
                                        {
                                            Product = r.Product,
                                            Quantity = r.Quantity
                                        });

I strongly suggest you create a viewmodel specifically to display the cart items.

public class CartItemsViewModel
{
    public List<ShoppingCartItemModel> Items { get; set; }
}

[HttpGet]
public ActionResult EditFromCart(int ProductID)
{

    ShoppingCart cart = GetCart();

    var viewModel = new CartItemsViewModel();

    viewModel.Items.AddRange(cart.items.Where(r => r.Product.ProductID == ProductID)
                .Select(r => new  ShoppingCartItemModel
                                {
                                    Product = r.Product,
                                    Quantity = r.Quantity
                                }));

    return View(viewModel);
}

In my example I use the .AddRange() method to take the results of the LINQ calls against the cart items and store them in the viewmodel's Items property.

Sign up to request clarification or add additional context in comments.

Comments

0

You must have to assign filtered value to cart like this.

cart.item = cart.items.Where(r => r.Product.ProductID == ProductID)
                      .Select(r => new  ShoppingCartItemModel
                                        {
                                            Product = r.Product,
                                            Quantity = r.Quantity
                                        }).ToList();

use ToList(); or FirstOrDefault() as per your condition

Comments

0

You need to hold the return value from the linq query on cart.Items in a variable and pass that to the View method. At the moment, the result of your query is being lost and the whole cart passed to the View method.

1 Comment

How to do that? Can you give my a simple example? thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.