How can I get ViewBag value in ASP.NET MVC ?

11,457

Solution 1

Personally, I'd solve it using the following:

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; }
    }
}

Controller:

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

  return View(model: model);
}

And your view:

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

Use models, that's what the whole point of MVC is. It makes life so much easier, not to mention the attributes you can apply to the model to further customize how it's displayed (templating, etc.). [Ab]Using dynamic the way you are is just going to lend your site to future problems, not to mentioned a bunch of cat-and-mouse going back and forth ("what did I name that property?", "what value type was 'foo' again?", ...), ignoring if there is anyone else that needs to work on the code you're generating.

Solution 2

Brad Christie's ViewModel approach is more sound, compiler can catch errors in your View earlier, instead of when it is more expensive to fix errors, i.e. during runtime; whereas if you used dynamic, you are basically on your own. And doing dynamic on anonymous type won't work either, having said that I once tried persisting anonymous types to dynamic, it's not an ugly hack; but I still want my Views errors be caught earlier instead, can be done via ViewModel.

If you still want to use dynamic, you just need a good serializer to persist anonymous values from Controller to View. You'll do this on your Controller:

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

And on your View:

 @{ 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>
}

In what I tried, Json Serializer is a good candidate for serialization needs, it can mimic the whole object graph

The Json Serializer component I used: http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

Share:
11,457
mirhagk
Author by

mirhagk

Updated on June 04, 2022

Comments

  • mirhagk
    mirhagk almost 2 years

    I'm using ASP.NET MVC Razor view engine, and I'm trying to use Viewbag. The following code will not work for me. In the controller I have

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

    and then in the view I have

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

    But it gives me an error saying the object course does not have a definition for Name. The debugger gives me the value, and shows everything correctly. Is there any way to get this to work? (I have a workaround already, I just would rather use this).

    Thanks in advance.