和助手是为 bool 和 bool 设计的CheckBox
?CheckBoxFor
属性(实际上,如果您查看源代码,您会看到它们强制将属性值强制转换为bool?
。检查InputHelper
源代码中的方法)。
在CheckBox
助手的情况下,输出将是这样的:
<input id="Foo" name="Foo" type="checkbox" value="true">
<input name="Foo" type="hidden" value="false">
如您所见,这些值被硬编码为真/假布尔值。您可以覆盖 value 属性,但这仅适用于复选框,而不适用于具有未选中复选框时的值的隐藏字段。使用非布尔字段的助手也会因为转换为布尔而导致您遇到麻烦?我上面提到过。
一种可能的解决方案是手动创建所需的 html。(您需要注意此处的 name 属性,因为它是 MVC 模型绑定器用于填充您的模型的内容)。在你看来写这样的东西:
<input id="Foo" name="Foo" type="checkbox" value="@item.ProjectId">
@* you could add another hidden input for when the checkbox is not checked *@
如果您正在使用模型元数据或如果您有复杂的绑定,这可能是一个问题,因为您需要手动设置 html 属性并小心使用 name 属性。
另一种选择是创建自己的 html 助手。这可以让您使用其他类型,而不仅仅是布尔值,并且应该期望复选框被选中时的值。这个想法是创建这样的东西:
public static class CustomHelpers
{
public static MvcHtmlString CheckBoxNonBooleanFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object checkedValue)
{
var fieldName = ExpressionHelper.GetExpressionText(expression);
var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var value = metadata.Model;
TagBuilder tag = new TagBuilder("input");
tag.Attributes.Add("name", fullBindingName);
tag.Attributes.Add("id", fieldId);
tag.Attributes.Add("type", "checkbox");
tag.Attributes.Add("value", (checkedValue ?? true).ToString());
if ((checkedValue != null && checkedValue.Equals(value))
||(checkedValue == null && value == null ))
{
tag.Attributes.Add("checked", "checked");
}
var validationAttributes = html.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
foreach (var key in validationAttributes.Keys)
{
tag.Attributes.Add(key, validationAttributes[key].ToString());
}
return new MvcHtmlString(tag.ToString());
}
}
可以在您的视图中使用此帮助程序,如下例所示(不要忘记将您的帮助程序命名空间包含到视图文件夹中 web.config 的视图命名空间设置中):
@Html.CheckBoxNonBooleanFor(m => m.Foo, 132)
它将生成以下 html,为您处理元数据属性、名称、检查属性等。
<input id="Foo" name="Foo" type="checkbox" value="132" data-val="true" data-val-number="The field Foo must be a number.">
如果需要,您可以轻松地对其进行扩展,添加另一个参数uncheckedValue,该参数将添加一个隐藏输入字段,其中包含当复选框保持未选中状态时所需的值。您还可以添加htmlAttributes参数以允许您传递额外的随机 html 属性。
作为最后的评论,只需仔细检查单选按钮是否不适合您的要求,因为您可以轻松地为同一字段设置多个具有不同 int 值的单选按钮。