The values are fixed in the HtmlHelper code. You could always create your own helper using the source for the existing helper as a guide or hand-code the HTML. The relevant snippets are below:
public static string CheckBox(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes) {
return htmlHelper.InputHelper(InputType.CheckBox, name, "true", true /* useViewData */, false /* isChecked */, true /* setId */, false /* isExplicitValue */, htmlAttributes);
}
public static string CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, IDictionary<string, object> htmlAttributes) {
// checked is an explicit parameter, but the value attribute is implicit so the dictionary's must take
// precedence.
RouteValueDictionary attributes = htmlAttributes == null ? new RouteValueDictionary() : new RouteValueDictionary(htmlAttributes);
attributes.Remove("checked");
return htmlHelper.InputHelper(InputType.CheckBox, name, "true", false /* useViewData */, isChecked, true /* setId */, false /* isExplicitValue */, attributes);
}
And from InputHelper():
if (inputType == InputType.CheckBox) {
// Render an additional <input type="hidden".../> for checkboxes. This
// addresses scenarios where unchecked checkboxes are not sent in the request.
// Sending a hidden input makes it possible to know that the checkbox was present
// on the page when the request was submitted.
StringBuilder inputItemBuilder = new StringBuilder();
inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));
TagBuilder hiddenInput = new TagBuilder("input");
hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
hiddenInput.MergeAttribute("name", name);
hiddenInput.MergeAttribute("value", "false");
inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
return inputItemBuilder.ToString();
}