I have a view model that contains a Product class type and an IEnumerable< Product > type. On the post the first level product object comes back binded from the viewmode
Travis's answer will address the issue. Here is another approach using EditorTemplates
You can use an Editor template
to display the Products and it will work fine.
1) Create a Folder called "EditorTemplates" under your Views/Home folder
2 ) Add a view called "Products
" inside that.
Add this code to that view
@model SO_MVC.Models.Product
@{
Layout = null;
}
<p>
@Html.LabelFor(x=>x.ID)
@Html.EditorFor(x=>x.ID)
</p>
<p>
@Html.LabelFor(x=>x.Name)
@Html.EditorFor(x=>x.Name)
</p>
<p>
@Html.LabelFor(x=>x.Price)
@Html.EditorFor(x=>x.Price)
</p>
@Html.HiddenFor(x=>x.Id)
and in your Main View, you can call this Editor template like this
@Html.EditorFor(m=>m.Products)
You are not using your lambda expression properly. You need to be accessing the Products list through the model. Try doing it like this:
@count = 0
foreach (var item in Model.Products)
{
<div>
@Html.LabelFor(model => model.Products[count].ID)
@Html.EditorFor(model => model.Products[count].ID)
</div>
<div>
@Html.LabelFor(model => model.Products[count].Name)
@Html.EditorFor(model => model.Products[count].Name)
</div>
<div>
@Html.LabelFor(model => model.Products[count].Price)
@Html.EditorFor(model => model.Products[count].Price)
</div>
@count++
}
Edit
Controller:
BoringStoreContext db = new BoringStoreContext();
public ActionResult Index()
{
ProductIndexViewModel viewModel = new ProductIndexViewModel
{
NewProduct = new Product(),
Products = db.Products
};
return View(viewModel);
}
[HttpPost]
public ActionResult Index(ProductIndexViewModel viewModel)
{
// work with view model
return View();
}
Model
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public class ProductIndexViewModel
{
public Product NewProduct { get; set; }
public List<Product> Products { get; set; }
}
public class BoringStoreContext
{
public BoringStoreContext()
{
Products = new List<Product>();
Products.Add(new Product() { ID = 1, Name = "Sure", Price = (decimal)(1.10) });
Products.Add(new Product() { ID = 2, Name = "Sure2", Price = (decimal)(2.10) });
}
public List<Product> Products { get; set; }
}
View:
@model Models.ProductIndexViewModel
@using (@Html.BeginForm())
{
<div>
@Html.LabelFor(model => model.NewProduct.Name)
@Html.EditorFor(model => model.NewProduct.Name)
</div>
<div>
@Html.LabelFor(model => model.NewProduct.Price)
@Html.EditorFor(model => model.NewProduct.Price)
</div>
for (int count = 0; count < Model.Products.Count; count++ )
{
<div>
@Html.LabelFor(model => model.Products[count].ID)
@Html.EditorFor(model => model.Products[count].ID)
</div>
<div>
@Html.LabelFor(model => model.Products[count].Name)
@Html.EditorFor(model => model.Products[count].Name)
</div>
<div>
@Html.LabelFor(model => model.Products[count].Price)
@Html.EditorFor(model => model.Products[count].Price)
</div>
}
<div>
<input type="submit" value="Add Product" />
</div>
}