title: What is an alternative to populating a DropDownList with a ViewBag?
body: <p>I have read that ViewBags are bad  and should be avoided if at all possible, and yet every training piece I have seen  (including the <a href="http://www.asp.net/mvc/overview/getting-started/introduction/getting-started" rel="nofollow">MVC 5 tutorial</a> and many SO answers) shows the style shown below to populate a DropDownList in the View. </p>
  
  <p>If it's one or two parameters, it's not noticeable, but a customer requested something very specific: a monster-sized table with 20 separate independent parameters used to filter the database query.  The example I have shown you is highly trimmed down. Just imagine that there are far more parameters, and can imagine how the Index Action would become very fat and not-simple. </p>
  
  <p>I can use <code>#region</code> blocks to collapse sections of the Action, which can help with organization and readability, but I wonder if there is a better way to do this. </p>
  
  <p>Here lies the big question: are there any alternatives to the use of ViewBags to populate DropDownLists from the Controller?</p>
  
  <p><strong>Excerpt from the Index Action in the Controller:</strong></p>
  
  <pre><code>public ActionResult Index(string campus = "CRA", string fy = "FY16", int? ageYr)
  {                       
      // Used to populate the DropDownLists in the HTML.BeginForm() block.
      ViewBag.CampusList = new SelectList(new List&lt;string&gt; { "CRA", "DRA", "MRA", "PRA" }, campus);
      ViewBag.FyList = new SelectList(new List&lt;string&gt; { "FY12", "FY13", "FY14", "FY15", "FY16" }, fy);                        
  
      // Optional Filter
      List&lt;int?&gt; ages = query.Select(m =&gt; (int?)m.AgeYrAtEndOfSy).Distinct().OrderBy(m =&gt; m).ToList();
      ages.Insert(0, null);
      ViewBag.AgeYrList = new SelectList(ages, ageYr);
  
      IEnumerable&lt;StudentSummaryLayer0&gt; query = db.StudentSummaryLayer0
          .Where(m =&gt; m.Campus == campus).Where(m =&gt; m.FY == fy);
  
      if (ageYr != null) query = query.Where(m =&gt; m.AgeYrAtEndOfSy == ageYr);            
  
      query = query.OrderBy(m =&gt; m.StudentName);
  
      return View(query.ToList());
  }
  </code></pre>
  
  <p><strong>Excerpt from the Index View:</strong></p>
  
  <pre><code>@model IEnumerable&lt;RoseDashboardFY16.Models.StudentSummaryLayer0&gt;
  
  @using (Html.BeginForm("Index", "StudentSummaryLayer0", FormMethod.Post))
  {
      &lt;div class="panel panel-default"&gt;
          &lt;div class="panel-heading"&gt;Filter results&lt;/div&gt;
          &lt;div class="panel-body"&gt;
              &lt;p&gt;
                  Required Filters: &lt;br /&gt;
                  &lt;strong&gt;Campus&lt;/strong&gt;: @Html.DropDownList("campus", (SelectList)ViewBag.CampusList)
                  &lt;strong&gt;FY&lt;/strong&gt;: @Html.DropDownList("fy", (SelectList)ViewBag.FyList)
              &lt;/p&gt;
  
              @*Imagine many more parameters.*@
              &lt;p style="line-height:2.0"&gt;
                  Optional Attribute Filters: &lt;br /&gt;                
                  &lt;span class="KeepTogether"&gt;
                      &lt;strong&gt;Age (Yr)&lt;/strong&gt;: @Html.DropDownList("ageYr", (SelectList)ViewBag.AgeYrList)
                  &lt;/span&gt;
              &lt;/p&gt;
  
              &lt;div&gt;&lt;input type="submit" value="Search" /&gt;&lt;input type="reset" value="Reset"&gt;&lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  }
  </code></pre>