This post shows how to process multiple checkboxes (dynamically and statically) in ASP.NET MVC.  Input form validation is easy to accomplish with System.ComponentModel.DataAnnotation.ValidationAtribute. Validating and processing multiple checkboxes at once is very tricky. I created a form model class that maps each checkbox group to a List<T> collection and implemented ValidationAttribute to handle the validation of each checkbox group.

 

CheckListAttribute class (CheckListAttribute.cs)

CheckListAttribute class validates each checkbox group depending on the minimum number of checkboxes required to be checked. The constructor takes 2 optional arguments:

  1. length (int) : minimum number checkboxes required to be checked. Default to 1.
  2. isFixed (bool) : if the length to fixed. Default to false.
public class CheckListAttribute : ValidationAttribute
    {
        int _length;
        bool _fixed;

        public override bool IsValid(object value)
        {
            int l = 0;

            if (value != null && typeof(List<int>) == value.GetType())
            {
                var v = (List<int>)value;
                l = v.Count;
            }
            else if (value != null)
            {
                var v = (List<string>)value;
                l = v.Count;
            }

            if (this._fixed)
            {
                return value != null && this._length == l;
            }
            else
            {
                return value != null && l >= this._length;
            }
        }

        public CheckListAttribute(int length = 1, bool isFixed = false)
        {
                
            this._length = length;
            this._fixed = isFixed;
        }
        
    }

 

FormModel Class (FormModel.cs)

FormModel class is for the form, which has two properties of Type List<T>. The CheckListAttribute is used to validate each property:

[CheckList(1, false)]
public List<string> StaticMultiBoxes { get; set; }

[CheckList(2, true)]
public List<int> DynamicMultiBoxes { get; set; }

 

Html Form Page (Index.chtml)

The HTML page contains a form of 2 checkbox groups:

  1. Static Checkboxes: these are statically listed checkboxes containing String values.
        <input name="StaticMultiBoxes"  id="Static1" type="checkbox" value="One" @Model.sChecked("One") /> <label for="Static1" > One</label><br />
        <input name="StaticMultiBoxes"  id="Static2" type="checkbox" value="Five" @Model.sChecked("Five") /> <label for="Static2"> Five</label><br />
        <input name="StaticMultiBoxes"  id="Static3" type="checkbox" value="Six" @Model.sChecked("Six") /> <label for="Static3"> Six</label><br />
  1. Dynamic Checkboxes: these are dynamically listed checkboxes. It is assumed that the list come from a database or other data source (a data class (FormModel. DynamicTableRows) has been mocked up for this exercise; please download source code at the end of this post).
           
            foreach (var i in Model.DynamicTableRows)
            {
                <input name="DynamicMultiBoxes" type="checkbox" value="@i.ID" @Model.dChecked(@i.ID)  /> <label> @i.Name</label><br />
               
            }

These lists when posted, the checked boxes would be combined and casted to the property FormModel.StaticCheckboxes and FormModel.DunamicCheckboxes because they possess the same input name.

 

Why Not Html.CheckBox()

At the time of this post, ASP.NET MVC do not have any helper method for Checkbox list. That is why I used normal HTML tags. If I use this helper method for multiple checkboxes, I am going to end up with an extra hidden input for each input field with values true/false and it will be double trouble for me.

 

HomeController (HomeController.cs)

These action methods handle the GET and POST request the normal way simultaneously.

       public ActionResult Index()
        {
            return View(new FormModel());
        }

        [HttpPost]
        public ActionResult Index(FormModel model)
        {
            if (ModelState.IsValid)
                return View("FormResult", model);
            else
                return View(model);
        }

The POST returns the model object to the form view and maintains the pre-completed form if the model validation fails. It renders the results view if it passes.

 

Extras

FormModel.sChecked() and FormModel.dChecked() help maintain the state of the submitted form. They kept the checked boxes when validation fails. The part-completed form are not lost for StaticCheckBoxes and DynamicCheckBoxes simultaneously.

 

FormModel.sChecked()

 

       public string sChecked( string input)
        {
            string ck="";
            if (this.StaticMultiBoxes != null && this.StaticMultiBoxes.Count > 0)
            {
                if (this.StaticMultiBoxes.Contains(input))
                {
                    ck = "checked=\"checked\"";
                }
            }
            return ck;
        }

 

FormModel.dChecked()

        public string dChecked(int input)
        {
            string ck = "";
            if (this.DynamicMultiBoxes != null && this.DynamicMultiBoxes.Count > 0)
            {
                if (this.DynamicMultiBoxes.Contains(input))
                {
                    ck = "checked=\"checked\"";
                }
            }
            return ck;
        }

 

In conclusion, this is a brief example of one of the simple ways to handle such tricky input-form lists. You could use this to build something more complex for your application in the future. I included the source project download link below.

Hope this helps!