title: ASP.NET MVC Checkbox Group
body: <p>I am trying to formulate a work-around for the lack of a "checkbox group" in ASP.NET MVC.  The typical way to implement this is to have check boxes of the same name, each with the value it represents.</p>
  
  <pre><code>&lt;input type="checkbox" name="n" value=1 /&gt;
  &lt;input type="checkbox" name="n" value=2 /&gt;
  &lt;input type="checkbox" name="n" value=3 /&gt;
  </code></pre>
  
  <p>When submitted, it will comma delimit all values to the request item "n".. so Request["n"] == "1,2,3" if all three are checked when submitted.  In ASP.NET MVC, you can have a parameter of n as an array to accept this post.</p>
  
  <pre><code>public ActionResult ActionName( int[] n ) { ... }
  </code></pre>
  
  <p><strong>All of the above works fine.</strong>  The problem I have is that when validation fails, the check boxes are not restored to their checked state.  Any suggestions.</p>
  
  <p><strong>Problem Code:</strong> (I started with the default asp.net mvc project)</p>
  
  <p>Controller</p>
  
  <pre><code>    public class HomeController : Controller
      {
          public ActionResult Index()
          {   var t = getTestModel("First");
              return View(t);
          }
  
          [AcceptVerbs(HttpVerbs.Post)]
          public ActionResult Index(TestModelView t)
          {   if(String.IsNullOrEmpty( t.TextBoxValue))
                  ModelState.AddModelError("TextBoxValue", "TextBoxValue required.");
              var newView = getTestModel("Next");
              return View(newView);
          }
  
          private TestModelView getTestModel(string prefix)
          {   var t = new TestModelView();
              t.Checkboxes = new List&lt;CheckboxInfo&gt;()
              {   new CheckboxInfo(){Text = prefix + "1", Value="1", IsChecked=false},
                  new CheckboxInfo(){Text = prefix + "2", Value="2", IsChecked=false} 
              };
              return t;
          }
      }
      public class TestModelView
      {   public string TextBoxValue { get; set; }
          public List&lt;CheckboxInfo&gt; Checkboxes { get; set; }
      }
      public class CheckboxInfo
      {   public string Text { get; set; }
          public string Value { get; set; }
          public bool IsChecked { get; set; }
      }
  }
  </code></pre>
  
  <p>ASPX</p>
  
  <pre><code>&lt;%
  using( Html.BeginForm() ){ 
  %&gt;  &lt;p&gt;&lt;%= Html.ValidationSummary() %&gt;&lt;/p&gt;
      &lt;p&gt;&lt;%= Html.TextBox("TextBoxValue")%&gt;&lt;/p&gt;
      &lt;p&gt;&lt;%  
      int i = 0;
      foreach (var cb in Model.Checkboxes)
      { %&gt;
          &lt;input type="checkbox" name="Checkboxes[&lt;%=i%&gt;]" 
              value="&lt;%= Html.Encode(cb.Value) %&gt;" &lt;%=cb.IsChecked ? "checked=\"checked\"" : String.Empty %&gt; 
              /&gt;&lt;%= Html.Encode(cb.Text)%&gt;&lt;br /&gt;
      &lt;%      i++;
      } %&gt;&lt;/p&gt;
      &lt;p&gt;&lt;input type="submit" value="submit" /&gt;&lt;/p&gt;
  &lt;%
  }
  %&gt;
  </code></pre>
  
  <p><strong>Working Code</strong></p>
  
  <p>Controller</p>
  
  <pre><code>[AcceptVerbs(HttpVerbs.Post)]
  public ActionResult Index(TestModelView t)
  {
      if(String.IsNullOrEmpty( t.TextBoxValue))
      {   ModelState.AddModelError("TextBoxValue", "TextBoxValue required.");
          return View(t); 
      }
      var newView = getTestModel("Next");
      return View(newView);
  }
  </code></pre>
  
  <p>ASPX</p>
  
  <pre><code>int i = 0;
  foreach (var cb in Model.Checkboxes)
  { %&gt;
      &lt;input type="checkbox" name="Checkboxes[&lt;%=i%&gt;].IsChecked" &lt;%=cb.IsChecked ? "checked=\"checked\"" : String.Empty %&gt; value="true" /&gt;
      &lt;input type="hidden"   name="Checkboxes[&lt;%=i%&gt;].IsChecked" value="false" /&gt;
      &lt;input type="hidden" name="Checkboxes[&lt;%=i%&gt;].Value" value="&lt;%= cb.Value %&gt;" /&gt;
      &lt;input type="hidden" name="Checkboxes[&lt;%=i%&gt;].Text" value="&lt;%= cb.Text %&gt;" /&gt;
      &lt;%= Html.Encode(cb.Text)%&gt;&lt;br /&gt;
  &lt;%      i++;
  } %&gt;&lt;/p&gt;
  &lt;p&gt;&lt;input type="submit" value="submit" /&gt;&lt;/p&gt;
  </code></pre>
  
  <p>Of course something similar could be done with Html Helpers, but this works.</p>