views:

37

answers:

1

Lets pretend we have a /Cart/Checkout view that lists every Product in the Cart, plus a TextBox with the Quantity (in my real world application I have more than Quantity). How would you update the Quantity? I have used the following code, but I'am looking for a "cleaner" way of doing it.

View

<% int i = 0; foreach(var product in Model.Products) { %>
<p>
    <%= Html.Encode(product.Name) %>
    <%= Html.TextBox("Quantity[" + i + "]", product.Quantity) %>
</p>
<% i++; } >

Controller

[AcceptVerbs(HttpVerbs.Post)]
// This would be a better way, but it does not work, any ideas?
//public ActionResult Checkout([Bind(Include = "ProductID, Quantity")] Product[] products)
public ActionResult Checkout(int[] productID, int[] Quantity)
{
    // Get the Product from cartRepository, update Quantity and SaveChanges().
}

How would you solve it?

+2  A: 

Make an edit model:

public class ProductEdit
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public int Quantity { get; set; }
}

Project onto the model for display:

[AcceptVerbs(HttpVerbs.Get)]
public Checkout(int cartId) 
{
    var model = (from c in Repository.Where(c.Id == cartId)
                 from p in c.Products
                 select new ProductEdit
                 { 
                     ProductId = p.ProductId,
                     Name = p.Name,
                     Quantity = p.Quantity
                 }).First();
    return View(model);
}

The form needs to use a specific name format for binding to a list:

<% int i = 0; foreach(var product in Model.Products) { %>
<p>
    <%= Html.Hidden(string.Format("products[{0}].ProductId", i), product.ProductId) %>
    <%= Html.Encode(product.Name) %>
    <%= Html.TextBox(string.Format("products[{0}].Quantity", i), product.Quantity) %>
</p>
<% i++; } >

Bind to the model on post:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CheckOut(int cartId, IEnumerable<ProductEdit> products) 
{
    // update products repository
}
Craig Stuntz
Thanks for your answer, but I can not get it to work. IEnumerable<ProductEdit> products are always null for me. Any ideas?
Johan Olsson
This suggests your form is using the wrong keys. You need to use the format `products[i].ProductId`, etc. I'll update the answer to clarify that.
Craig Stuntz
Yeah, I discovered that products[i].ProductId was the right way and not products.ProductID[i]. Now everything is working correct, thanks!
Johan Olsson