I am trying to display a collection of all products (using a view model) in my Pro()
method
Models
public class Product
{
public Product() { this.AddDate = DateTime.Now; }
public int ProductId { get; set; }
[Required(ErrorMessage = "Enter Product name")]
[StringLength(160)]
public string ProductName { get; set; }
[Required(ErrorMessage = "Enter Product Description")]
[StringLength(500)]
public string ProductDescription { get; set; }
public DateTime AddDate { get ; private set; }
[Required(ErrorMessage = "Select Category")]
[Display(Name="Category")]
public string Category { get; set; }
[Required(ErrorMessage = "Location")]
public bool location { get; set; }
}
public class ProductPicture
{
public int id { get; set; }
public int ProductId { get; set; }
[Required(ErrorMessage ="Please Select Picture")]
public string pictureurl { get; set; }
}
View model
public class ProductViewModel
{
public int ProductId { get; set; }
public string ProductName { get; set; }
[Required(ErrorMessage = "Enter Product Description")]
[StringLength(500)]
public string ProductDescription { get; set; }
public DateTime AddDate { get; private set; }
[Required(ErrorMessage = "Select Category")]
[Display(Name = "Category")]
public string Category { get; set; }
[Required(ErrorMessage = "Location")]
public bool location { get; set; }
public IEnumerable<ProductPicture> ProductPictures { get; set; }
}
Controller method
public ActionResult pro()
{
ProductViewModel product = new ProductViewModel();
var pro = db.Products.ToList();
if (pro != null)
{
product.ProductName = pro.ProductName;
product.ProductDescription = pro.ProductDescription;
product.Payextra = pro.Payextra;
product.location = pro.location;
product.ProductPictures = db.ProductPictures.Where(m => m.ProductId == pro.Select(m=>m.ProductId));
}
return View(product);
}
Currently this is throwing the following exception
since i am trying to map complete list with a single object "=" operator can not be applied to int to IEnumerable. logically i am doing something wrong , so please help me to select current id from IEnumerable and map with current productpicture list and at last create the collection of same viewmodel which can be displayed in view.
You need to change the method to project the collection of Product
to a collection of ProductViewModel
and return that to the view.
public ActionResult Pro()
{
var pictures = db.ProductPictures;
var model = db.Products.Select(p => new ProductViewModel
{
ProductName = p.ProductName,
ProductDescription = p.ProductDescription,
....
ProductPictures = pictures.Where(x => x.ProductId == p.ID)
};
return View(model);
}
Then in the view
@model IEnmerable<ProductViewModel>
<table>
<thead>
<tr>
<th>@Html.DisplayNameFor(m => m.ProductName)</th>
....
</tr>
</thead>
<tbody>
@foreach(var product in Model)
{
<tr>
<td>@Html.DisplayFor(m => product.ProductName)</td>
....
Side note: I recommend you change the name of the method to Index()
which means a user can navigate to it using .../Products
(assuming your using the default routing), or at least to a name that indicates your displaying all products (the current url will be ../Products/Pro
which does not convey any useful meaning to a user)