如何让Html.CheckBoxFor()在字符串字段上工作?

我正在使用带有Razor和C#的ASP.NET MVC3。 我正在制作各种表单构建器,所以我有一个具有以下对象集合的模型:

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

MyFormType只是一个枚举,告诉我表单字段是复选框,文本框,文件上传,还是其他什么。 我的编辑器模板看起来像这样(请参阅注释):

〜/查看/ 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! } } 

我尝试将m.Value转换/转换为CheckBoxFor()的lambda表达式中的bool,但是这引发了错误。 我只是手动构造一个复选框输入,但CheckBoxFor()似乎做了两件我似乎无法复制的事情:

  1. 创建一个隐藏的输入,以某种方式由复选框填充。 这似乎是模型绑定器的选择。
  2. 从对象生成名称,以便模型绑定器将值获取到正确的属性中。

有没有人知道在字符串上使用CheckBoxFor()的方法,或者手动复制其function的方法,以便我可以使这个工作?

您还可以在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; } } 

你的观点是这样的:

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

如果要避免exception,请使用Boolean.TryParse。

一种方法是创建自己的htmlhelper扩展方法。

  public static MvcHtmlString CheckBoxStringFor(this HtmlHelper html, Expression> expression) { // get the name of the property string[] propertyNameParts = expression.Body.ToString().Split('.'); string propertyName = propertyNameParts.Last(); // get the value of the property Func compiled = expression.Compile(); string booleanStr = compiled(html.ViewData.Model); // convert it to a boolean bool isChecked = false; Boolean.TryParse(booleanStr, out isChecked); TagBuilder checkbox = new TagBuilder("input"); checkbox.MergeAttribute("id", propertyName); checkbox.MergeAttribute("name", propertyName); checkbox.MergeAttribute("type", "checkbox"); checkbox.MergeAttribute("value", "true"); if (isChecked) checkbox.MergeAttribute("checked", "checked"); TagBuilder hidden = new TagBuilder("input"); hidden.MergeAttribute("name", propertyName); hidden.MergeAttribute("type", "hidden"); hidden.MergeAttribute("value", "false"); return MvcHtmlString.Create(checkbox.ToString(TagRenderMode.SelfClosing) + hidden.ToString(TagRenderMode.SelfClosing)); } 

用法与CheckBoxFor helper相同(e.Value是一个字符串)

 @Html.CheckBoxStringFor(e => e.Value) 

使用Checkbox,这种简单的方法工作正常

 @Html.CheckBox("IsActive", Model.MyString == "Y" ? true : false) 

我也有这个问题,但无法修改视图模型。 试过mdm20s解决方案,但我怀疑它不适用于集合属性(它不会将索引添加到名称和id,如本机html助手)。 要解决此问题,您可以使用Html.CheckBox。 它添加了正确的索引,您可以自己传递复选框的值。

如果你真的想使用一个表达式,你总是可以写一个类似于mdm20s的包装器,但是在TryParse之后用return Html.CheckBox("propertyName", isChecked)替换所有内容。 显然,您还需要using System.Web.Mvc.Html添加。