title: How do I sort a list of entities using ViewModel instead of ViewBag?
body: <p>I am using ViewBag to help me sort a list of students found within a list of classes.  I have read that ViewBag is something that should be avoided at all costs attempting to build a proper MVC project.  </p>
  
  <p>When viewing the page that the below code generates, one is able to sort through a list of students in a variety of ways (First Name by alpha, Last name by alpha, date enrolled, etc), and view only a limited number of students per page.</p>
  
  <p>I do not know exactly how to translate my code to use a ViewModel in place of my current design.</p>
  
  <p>I am using the following code:</p>
  
  <p>Model (Student):</p>
  
  <pre><code>public class Student
  {
      public int StudentID { get; set; }
      public string LastName { get; set; }
      public string FirstMidName { get; set; }
      public string Email { get; set; }
      public DateTime EnrollmentDate { get; set; } 
      public virtual ICollection&lt;Enrollment&gt; Enrollments { get; set; }
  }
  </code></pre>
  
  <p>Model (Enrollment):</p>
  
  <pre><code>public class Enrollment
  {
      public int EnrollmentID { get; set; }
      public int CourseID { get; set; }
      public int StudentID { get; set; }
      public string Grade { get; set; } // pass, fail, incomplete
      public virtual Course Course { get; set; } 
      public virtual Student Student { get; set; } 
  }
  </code></pre>
  
  <p>(I also have a Course model, but it is not referenced directly by the controller below, so I will omit it here - if it is necessary to show its details, please let me know.)</p>
  
  <p>Controller:</p>
  
  <pre><code>public class StudentController : Controller
  {
      private SchoolContext db = new SchoolContext();
  
      //
      // GET: /Student/
  
      public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
      {
          ViewBag.CurrentSort = sortOrder;
          ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
          ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
          ViewBag.FNameSortParm = sortOrder == "FName" ? "FName desc" : "FName";
          ViewBag.EmailSortParm = sortOrder == "Email" ? "Email desc" : "Email";
  
          if (Request.HttpMethod == "GET")
          {
              searchString = currentFilter;
          }
          else
          {
              page = 1;
          }
          ViewBag.CurrentFilter = searchString;
  
          var students = from s in db.Students
                         select s;
          if (!String.IsNullOrEmpty(searchString))
          {
              students = students.Where(s =&gt; s.LastName.ToUpper().Contains(searchString.ToUpper())
                                     || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
          }
          switch (sortOrder)
          {
              case "Name desc":
                  students = students.OrderByDescending(s =&gt; s.LastName);
                  break;
              case "Date":
                  students = students.OrderBy(s =&gt; s.EnrollmentDate);
                  break;
              case "Date desc":
                  students = students.OrderByDescending(s =&gt; s.EnrollmentDate);
                  break;
              case "FName":
                  students = students.OrderBy(s =&gt; s.FirstMidName);
                  break;
              case "FName desc":
                  students = students.OrderByDescending(s =&gt; s.FirstMidName);
                  break;
              case "Email":
                  students = students.OrderBy(s =&gt; s.Email);
                  break;
              case "Email desc":
                  students = students.OrderByDescending(s =&gt; s.Email);
                  break;
              default:
                  students = students.OrderBy(s =&gt; s.LastName);
                  break;
          }
          int pageSize = 4;
          int pageNumber = (page ?? 1);
          return View(students.ToPagedList(pageNumber, pageSize));
      }
  </code></pre>
  
  <p>And my view:</p>
  
  <pre><code>@model PagedList.IPagedList&lt;MVCAppName.Models.Student&gt;
  
  @{
      ViewBag.Title = "Students";
  }
  
  &lt;h2&gt;Students&lt;/h2&gt;
  
  &lt;p&gt;
      @Html.ActionLink("Create New", "Create")
  &lt;/p&gt;
  @using (Html.BeginForm())
  {
      &lt;p&gt;
          Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string) &amp;nbsp;
          &lt;input type="submit" value="Search" /&gt;&lt;/p&gt;
  }
  &lt;table&gt;
      &lt;tr&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;
          @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
      &lt;/th&gt;
      &lt;th&gt;
          @Html.ActionLink("First Name", "Index", new { sortOrder = ViewBag.FNameSortParm, currentFilter = ViewBag.CurrentFilter })
      &lt;/th&gt;
      &lt;th&gt;
          @Html.ActionLink("Email", "Index", new { sortOrder = ViewBag.EmailSortParm, currentFilter = ViewBag.CurrentFilter })
      &lt;/th&gt;
      &lt;th&gt;
          @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
      &lt;/th&gt;
  &lt;/tr&gt;
  
  @foreach (var item in Model) {
      &lt;tr&gt;
          &lt;td&gt;
              @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
              @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
              @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
          &lt;/td&gt;
          &lt;td&gt;
              @Html.DisplayFor(modelItem =&gt; item.LastName)
          &lt;/td&gt;
          &lt;td&gt;
              @Html.DisplayFor(modelItem =&gt; item.FirstMidName)
          &lt;/td&gt;
          &lt;td&gt;
              @Html.DisplayFor(modelItem =&gt; item.Email)
          &lt;/td&gt;
          &lt;td&gt;
              @Html.DisplayFor(modelItem =&gt; item.EnrollmentDate)
          &lt;/td&gt;
      &lt;/tr&gt;
  }
  
  &lt;/table&gt;
  
  &lt;div&gt;
      Page @(Model.PageCount &lt; Model.PageNumber ? 0 : Model.PageNumber)
      of @Model.PageCount
      &amp;nbsp;
      @if (Model.HasPreviousPage)
      {
          @Html.ActionLink("&lt;&lt;", "Index", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter  })
          @Html.Raw("&amp;nbsp;");
          @Html.ActionLink("&lt; Prev", "Index", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter  })
      }
      else
      {
          @:&lt;&lt;
          @Html.Raw("&amp;nbsp;");
          @:&lt; Prev
      }
      &amp;nbsp;
      @if (Model.HasNextPage)
      {
          @Html.ActionLink("Next &gt;", "Index", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter  })
          @Html.Raw("&amp;nbsp;");
          @Html.ActionLink("&gt;&gt;", "Index", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter  })
      }
      else
      {
          @:Next &gt;
          @Html.Raw("&amp;nbsp;")
          @:&gt;&gt;
      }
  &lt;/div&gt;
  </code></pre>