Как я могу получить значение ViewBag в ASP.NET MVC?

Я использую движок представления ASP.NET MVC Razor и пытаюсь использовать Viewbag. Следующий код не будет работать для меня. В контроллере у меня есть

ViewBag.courses = new List<dynamic>();
ViewBag.courses.Add(new { Name = "Math" });

а потом по моему мнению

@foreach(dynamic course in ViewBag.courses)
{
    <li>@course.Name</li>
}

Но это дает мне ошибку, говоря, что у курса объекта нет определения для Имени. Отладчик дает мне значение и показывает все правильно. Есть ли способ заставить это работать? (У меня уже есть обходной путь, я просто предпочел бы использовать это).

Заранее спасибо.

2 ответа

Решение

Лично я бы решил это, используя следующее:

public class Course
{
    public String Name { get; set; }
}

public class CoursesViewModel
{
    private IList<Course> courses;

    public IList<Course> Courses{
      get { return this.courses ?? (this.courses = new List<Course>()); }
      set { this.courses = value; }
    }
}

контроллер:

public ActionResult Index()
{
  CoursesViewModel model = new CoursesViewModel();
  model.Courses.Add(new Course { Name = "Math" });

  return View(model: model);
}

И ваш взгляд:

@model CoursesViewModel
@* ... *@
<ul>
@foreach (Course course in Model.Courses)
{
  <li>@course.Name</li>
}
</ul>
@* ... *@

Используйте модели, вот в чем весь смысл MVC. Это делает жизнь намного проще, не говоря уже об атрибутах, которые можно применить к модели для дальнейшей настройки ее отображения (шаблонов и т. Д.). [Ab] Использование dynamic вы просто одолжите свой сайт для решения будущих проблем, не говоря уже о том, что все в порядке ("как я назвал это свойство?", "какой тип значения снова был" foo ")?", ...), игнорируя, если есть кто-то еще, кто должен работать над кодом, который вы генерируете.

Подход Брэда Кристи в ViewModel является более надежным, компилятор может отлавливать ошибки в вашем View раньше, а не тогда, когда исправление ошибок обходится дороже, т.е. во время выполнения; тогда как, если вы использовали динамический, вы в основном самостоятельно. И выполнение динамического для анонимного типа также не будет работать, сказав, что я однажды пытался сохранить анонимные типы в динамическом, это не уродливый хак; но я все еще хочу, чтобы мои ошибки Views были перехвачены ранее, это можно сделать через ViewModel.

Если вы все еще хотите использовать динамический, вам просто нужен хороший сериализатор для сохранения анонимных значений от Controller до View. Вы сделаете это на вашем контроллере:

 return View((object)r.JsSerialize());

И на ваш взгляд:

 @{ dynamic r = ((string)Model).JsDeserialize(); }


 @foreach (var item in r) {
 <tr>
  <td>
   @item.Person.Lastname
  </td>
  <td>
   @item.Person.Firstname
  </td>
  <td>
   @item.Person.FavoriteNumber
  </td>
  <td>
   <input type="checkbox" disabled="disabled" @(item.IsQualified ? "checked" : "") />
  </td>
 </tr>
}

В том, что я пробовал, Json Serializer является хорошим кандидатом для нужд сериализации, он может имитировать весь граф объектов

Компонент Json Serializer, который я использовал: http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

Другие вопросы по тегам