1

I started in a new job, we must create an app using MVC 5, i have no experience in .NET so I not sure if I am using the best practice.

I have 2 models ClassRom and Students,

public class Student
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

 public class ClassRom
{
    public int ID { get; set; }
    public string Name { get; set; }
}

I am passing a ICollection<> from a controller to a views using ViewBag

IList<ClassRom> classes = db.Classes.ToList();
IList<Student> students = db.Students.ToList();
ViewBag.classes = classes;
ViewBag.students = students;
return View();

And using the data in a view

<div>
@foreach (var student in ViewBag.students)
{
    <div>@student.Name</div>
    <div>@student.Age</div>
}  

It works pretty well for what I need, anyway if I add a Scaffolded Controller, it will create something like this:

public ActionResult Index()
    {
        return View(db.Students.ToList());
    }

And the view

@model IEnumerable<School.Models.Student>
@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Name)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Age)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
        @Html.ActionLink("Details", "Details", new { id=item.ID }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.ID })
    </td>
</tr>

}

My question is, Am i doing it wrong? should I use @model IEnumerable instead of ViewBag?

Ugo Guazelli
  • 703
  • 3
  • 8
  • 19
  • 1
    Some people use ViewBag to transfer data, some users strongly typed approach(your second approach). I personally prefer to avoid ViewData/ViewBag and try to use the strongly typed approach. One difference is, I do not use the entity classes created from my ORM tool(that will make my views tightly coupled to that classes ), Instead i use view specific view models(simply POCOs). [Here is a good read](http://stackoverflow.com/questions/11262034/mvc-viewbag-best-practice) to give you some more ideas – Shyju Jul 25 '16 at 16:52

3 Answers3

2

It is better to use @model IEnumerable because:

  • It is statically typed. A ViewBag is dynamic so you lose type safety.
  • It leads to a cleaner design where components (ViewModels and Models can be reused).

PS: ClassRom should be ClassRoom I believe.

Good luck!

user2609980
  • 10,264
  • 15
  • 74
  • 143
  • How does using the `@model` over `ViewBag` (or the other way around) make a model/viewmodel more reusable? – Luke Jul 25 '16 at 17:04
  • @Luke When using a `ViewBag` to pass values from the controller to the view there is no `Model` or `ViewModel`. So no way to reuse the classes. – user2609980 Jul 25 '16 at 17:50
  • That makes no sense to me, of course you can reuse the classes. – Luke Jul 25 '16 at 18:04
2

Under normal circumstances you should be using the model using @model and @Model in your view. The @model (lowercase) is used to define the TYPE of your model.

If you were passing an instance of your own class such as the below:

public class MyClass
{
    public IEnumerable<string> MyProperty { get; set; }
}

You would define the type as @model MyClass and access the values using @Model.MyProperty in your view.

Generally, the best practice would not be to use the ViewBag to pass your model to the view and this will not be accessible using @Model in your view. In order for the values to be accessed in your view using @Model, you would need to pass be returned like so:

public ActionResult Index()
{
    // Create your model and set the values
    var myModel = new MyClass
    {
        MyProperty = new List<string> { "First Value", "Second Value" }
    };

    // Return the model back to your view for access using @Model
    return View(myModel);
}
Luke
  • 22,826
  • 31
  • 110
  • 193
1

I would always use a model when creating a view. The viewbag is too loose for my liking. IEnumerable is fine for the model as it's an immutable collection from the models perspective.

Rich Linnell
  • 973
  • 5
  • 14