Here's how we have been using model binder and UpdateModel of ASP.NET MVC to persist form data consisting of "Check all that apply" type questions.
The Model
This C# contains a Program class which in turn contains a list of Disciplines.
public class Program
{
public virtual Guid ID { get; set; }
public virtual IList<Discipline> Disciplines { get; set; }
public Program()
{
Disciplines = new List<Discipline>();
var discipline = new[] { "Dance", "Literary Arts", "Media" };
foreach ( var detail in discipline )
{
Disciplines.Add( new Discipline { Title = detail } );
}
}
}
public class Discipline
{
public virtual Guid ID { get; set; }
public virtual string Title { get; set; }
public virtual bool? IsSelected { get; set; }
}
The properties are marked virtual as we use NHibernate for the ORM. When a Program instance is created, we also pre-populate its collection of Disciplines. Now, it's true that from the relational point of view, this leads to what looks like a 2nd-normal form schema. But, that post is for another day...
The View
<% for (int i = 0; i < Model.Disciplines.Count; i++) { %>
<p>
<%= Model.Disciplines[i].Title %><br />
<input type="hidden" name="Disciplines.Index" value="<%= i %>" />
<input type="hidden" name="Disciplines[<%= i %>].Title" value="<%= Model.Disciplines[i].Title %>" />
<%= Html.RadioButton( "Disciplines[" + i + "].IsSelected", "true", Model.Disciplines[i].IsSelected ?? false ) %> Yes
<%= Html.RadioButton( "Disciplines[" + i + "].IsSelected", "false", !(Model.Disciplines[i].IsSelected ?? true) ) %> No
</p>
<% } %>
You will see that we check for the null booleans, which is really a way to check whether the end user has selected Yes, No or nothing.
The Controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Program(FormCollection collection)
{
var program = new Program();
UpdateModel( program, new[]{ "Disciplines" } );
//call our service to persist the new program
_programService.SaveOrUpdate( program );
return View( program );
}