Как отмечалось, вы должны стараться избегать ViewBag и использовать вместо этого строго типизированные ViewModels.
При этом ваша проблема в том, что ViewBag в основном IDictionary<string, object>
.Поэтому, если вы получите доступ к ViewBag["ProductsList"]
, вы получите object
, и, следовательно, ошибка
'object' не содержит определения для 'ProductID'
Вам нужно привести этот object
к исходному типу, чтобы получить доступ к свойствам.Но у вас нет исходного типа для приведения, потому что вы в первую очередь использовали анонимный тип для заполнения ViewBag.
Чистое решение - ввести ViewModels:
public class ProductViewModel {
public int ProductID { get; set; }
public string ProductName { get; set; }
public string CategoryName { get; set; }
}
public class ProductsPageViewModel {
public ProductsPageViewModel {
ProductsList = new List<ProductViewModel>();
}
public ICollection<ProductViewModel> ProductsList { get; set; }
}
PassViewModel для View в контроллере:
public ActionResult Products() {
var productList =
(from p in db.Products
join c in db.Categories
on p.CategoryID equals c.CategoryID
select new ProductViewModel {
ProductID = p.ProductID,
ProductName = p.ProductName,
CategoryName = c.CategoryName
}).ToList();
var viewModel = new ProductsPageViewModel {
ProductsList = productList
};
return View("Products", viewModel);
}
В представлении Products.cshtml определите, какую ViewModel вы ожидаете, с помощью директивы @model
:
@model ProductsPageViewModel
@* ... *@
@foreach (var item in Model.ProductsList) {
@item.ProductID
}