‘object’ не содержит определения для ‘X’

У меня была эта проблема раньше, и я ее не разрешил. У меня есть список (сгенерированный в controllerе MVC3):

ViewBag.Languages = db.Languages .Select(x => new { x.Name, x.EnglishName, x.Id }) .ToList(); 

и на моей странице (Razor) я пытаюсь пройти через нее:

 foreach (var o in ViewBag.Languages) { string img = "Lang/" + o.EnglishName + ".png"; @* work *@ } 

но ссылка на o.EnglishName терпит неудачу с ошибкой:

‘object’ не содержит определения для ‘EnglishName’

хотя любопытно, что если я введу в окно Immediate (во время отладки):

 o { Name = བོད་སྐད་, EnglishName = Tibetan, Id = 31 } EnglishName: "Tibetan" Id: 31 Name: "བོད་སྐད་" 

так что очевидно, что поле есть. В чем моя проблема?

Вы используете анонимный объект здесь:

 ViewBag.Languages = db.Languages .Select(x => new { x.Name, x.EnglishName, x.Id }) .ToList(); 

Анонимные объекты генерируются компилятором как internal . Представления Razor автоматически компилируются в отдельную сборку по времени выполнения ASP.NET. Это означает, что вы не можете получить доступ к анонимным объектам, созданным в ваших controllerах.

Поэтому, чтобы исправить вашу проблему, вы можете определить модель представления:

 public class LanguageViewModel { public int Id { get; set; } public string Name { get; set; } public string EnglishName { get; set; } } 

а затем в вашем controllerе используйте эту модель представления:

 ViewBag.Languages = db.Languages .Select(x => new LanguageViewModel { Name = x.Name, EnglishName = x.EnglishName, Id = x.Id }) .ToList(); 

И теперь, когда у вас есть модель просмотра, следующим улучшением вашего кода является, конечно, избавиться от этого дерьма ViewBag который мне тошнит от просмотра и просто использовать модели представления и сильную типизацию:

 public ActionResult Foo() { var model = db .Languages .Select(x => new LanguageViewModel { Name = x.Name, EnglishName = x.EnglishName, Id = x.Id }) .ToList(); return View(model); } 

и, конечно же, имеют строго типизированное представление:

 @model IEnumerable @Html.DisplayForModel() 

а затем определите соответствующий шаблон отображения, который будет автоматически отображаться движком ASP.NET MVC для каждого элемента модели представления, так что вам даже не нужно писать одиночный foreach в ваших представлениях ( ~/Views/Shared/DisplayTemplates/LanguageViewModel.cshtml ):

 @model LanguageViewModel ... generate the image or whatever you was attempting to do in the first place 

Это приводило меня в порядок, пока я не проверил свой код и не нашел это:

 class AdsViewModel { public int Id { get; set; } public string City { get; set; } public string CompanyName { get; set; } public string ContactName { get; set; } public string UserEmail { get; set; } public string ContactPhone { get; set; } public string ShortTitle { get; set; } public string AdUrl { get; set; } } 

Изменение его на:

 public class AdsViewModel 

Починил это.

Используйте ViewData вместо ViewBag.

 ViewData["Lang"] = db.Languages .Select(x => new { x.Name, x.EnglishName, x.Id }) .ToList(); 

затем

 foreach (var o in (dynamic) ViewData["Lang"]) { string img = "Lang/" + o.EnglishName + ".png"; @* work *@ } 

Это может произойти, если имя вашего classа не совпадает с именем файла (я знаю, что это глупо, но это может вам помочь)

  • Сохранение данных многих из многих отношений в MVC Создание представления
  • Render Razor Просмотр строки в ASP.NET Core
  • Почему Html.Raw ускоряет амперсанд в привязном теге в ASP.NET MVC 4?
  • Условно измените class CSS в режиме Razor
  • ASP.Net MVC 4 Форма с двумя кнопками / действиями отправки
  • Как редактировать несколько моделей в одном представлении Razor
  • Метод Razor ViewEngine HTML.Checkbox создает скрытый ввод. Зачем?
  • asp.net MVC3 razor: отображение actionlink на основе роли пользователя
  • ASP.NET MVC 3 Razor - Добавление classа в EditorFor
  • Как сделать раздел в частичном представлении в MVC3?
  • MVC3 Razor DropDownListFor Enums
  • Давайте будем гением компьютера.