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

本文关键字:字段 字符串 工作 何使 Html CheckBoxFor | 更新日期: 2023-09-27 18:06:52

我正在使用ASP。NET mvc与Razor和c#。我正在制作各种表单构建器,因此我有一个模型,该模型包含以下对象:

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()的方法,或者手动复制其功能的方法,以便我可以使此工作?

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

您还可以在视图模型上添加一个属性:

    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!
    }
}

使用布尔。

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

    public static MvcHtmlString CheckBoxStringFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, string>> expression)
    {
        // get the name of the property
        string[] propertyNameParts = expression.Body.ToString().Split('.');
        string propertyName = propertyNameParts.Last();
        // get the value of the property
        Func<TModel, string> 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)

使用复选框,这个简单的方法很好

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

我也有这个问题,但无法修改视图模型。尝试mdm20的解决方案,但我怀疑它不工作的集合属性(它不添加索引的名称和id像本地html助手)。为了克服这个问题,可以使用Html。复选框。它会添加适当的索引,您可以自己传递复选框的值。

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