Search code examples
c#asp.net-mvcasp.net-mvc-3razormvc-editor-templates

How can I make Html.CheckBoxFor() work on a string field?


I'm using ASP.NET MVC3 with Razor and C#. I am making a form builder of sorts, so I have a model that has a collection of the following object:

public class MyFormField
{
    public string Name { get; set; }
    public string Value { get; set; }
    public MyFormType Type { get; set; }
}

MyFormType is just an enum that tells me if the form field is a checkbox, or textbox, or file upload, or whatever. My editor template looks something like this (see the comment):

~/Views/EditorTemplates/MyFormField.cshtml

@model MyFormField
@{
    switch (Model.Type)
    {
        case MyFormType.Textbox:
            @Html.TextBoxFor(m => m.Value)
        case MyFormType.Checkbox:
            @Html.CheckBoxFor(m => m.Value)  // This does not work!
    }
}

I tried casting/converting the m.Value to a bool in the lambda expression for CheckBoxFor(), but that threw an error. I would just manually construct a checkbox input, but CheckBoxFor() seems to do two things that I can't seem to replicate:

  1. Creates a hidden input that somehow gets populated by the checkbox. This appears to be what the model binder picks up.
  2. Generates the name form the object so that the model binder gets the value into the right property.

Does anyone know a way around using CheckBoxFor() on a string, or a way to replicate its functionality manually, so that I can make this work?


Solution

  • You could also add a property on your viewmodel:

        public class MyFormField
        {
            public string Name { get; set; }
            public string Value { get; set; }
    
            public bool CheckBoxValue
            {
                get { return Boolean.Parse(Value); }
            }
    
            public MyFormType Type { get; set; }
        }
    

    Your view would be something like this:

    @model MyFormField
    @{
        switch (Model.Type)
        {
            case MyFormType.Textbox:
                @Html.TextBoxFor(m => m.Value)
            case MyFormType.Checkbox:
                @Html.CheckBoxFor(m => m.CheckBoxValue)  // This does work!
        }
    }
    

    Use Boolean.TryParse if you want to avoid exceptions.