Я не уверен, исходя из вашего примера кода, почему вы могли бы получить эту ошибку, похоже, есть проблема с @foreach (var item in Model.Categories)
.
Что я вижу и рекомендую, так это следоватьс подходом модели представления, но не присоединяйте объекты в модель представления.Модели представления должны быть простыми классами POCO, которые предоставляют достаточно деталей для представления, и ничего более.Причина этого заключается в том, чтобы помочь повысить производительность (меньше чтения и передачи данных) и повысить безопасность.(нет данных, отправленных клиенту, которых вы не ожидаете увидеть, например, представленных в инструментах отладки, и убедитесь, что объекты не отправляются обратно на сервер с непреднамеренным редактированием, снова через инструменты отладки, доверенные, подключенные и зафиксированные вконтекст.)
Я бы предложил создать CategorySummaryViewModel и AdSummaryViewModel, содержащие только идентификатор и имя для начала.Отметить все модели просмотра как Serializable.Затем, когда вы заполняете вашу ViewModel:
[Serializable]
public class AdsPageViewModel
{
public List<CategorySummaryViewModel> Categories { get; set; } = new List<CategorySummaryViewModel>();
public List<AdSummaryViewModel> Ads { get; set; } = new List<AdSummaryViewModel>();
}
public ActionResult Index()
{
var mymodel = new AdsPageViewModel
{
Categories = db.Categories.Select(x=> new CategorySummaryViewModel
{
Id = x.Id,
Name = x.Name // Append other fields if necessary for the view.
}).ToList(),
Ads = db.Ads.Select(x => new AdSummaryViewModel
{
Id = x.Id,
Name = x.Name
}).ToList()
};
return View(mymodel);
}
Это будет казаться большим количеством кода / усилий, чем просто передача сущностей.Вы можете использовать такой инструмент, как Automapper, чтобы упростить это, и использовать .ProjectTo<T>
, чтобы получить те же преимущества, что и выше.Эти преимущества включают в себя то, что при использовании .Select()
оператор EF SQL отправляется в базу данных, а данные, возвращаемые из базы данных, включают только те поля, которые нужны нашей модели представления.Меньше данных по проводам = быстрее и меньше памяти требуется на сервере приложений и клиенте для запроса.Это также гарантирует, что наше представление может видеть только те поля, которые мы хотим видеть.Кто-то, использующий F12 в нашем клиенте, не может проверить другие FK и поля, которые скрыты только потому, что у нас нет элементов управления, видимых на странице.Мы также гарантируем, что наше приложение не принимает объекты обратно от клиента, где будет соблазн присоединить их к контексту и сохранить их.(кажется простым, но уязвимым для хакеров, изменяющих данные сущности с помощью тех же инструментов отладки и повреждающих сохраненные данные.)
Дайте возможность использовать сериализуемые модели представления POCO, чтобы создать данные представления и посмотреть, по-прежнему ли выполучить любое исключение при рендеринге дочерних коллекций.Я подозреваю, что если проблема не устранена, в вашем коде может быть деталь, которая не описана здесь.