Asp.net mvc 使用RadioButton对一组单选按钮进行编码的正确方法

Asp.net mvc 使用RadioButton对一组单选按钮进行编码的正确方法,asp.net-mvc,checkbox,radio-button,radiobuttonfor,Asp.net Mvc,Checkbox,Radio Button,Radiobuttonfor,根据我的研究,在MVC中编写复选框的正确方法如下 @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) 这将呈现复选框,呈现复选框的标签,并使标签可单击,这意味着单击标签也会切换复选框 但是对于单个视图模型字段有多个复选框的情况又如何呢?(例如,可能每个复选框代表一个整数值内的一位。)或者,更好的是,单选按钮,其中始终有多个选项与同一字段关联 在这些情况下,上面的代码似乎有问题。不是所有元素都与

根据我的研究,在MVC中编写复选框的正确方法如下

@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
这将呈现复选框,呈现复选框的标签,并使标签可单击,这意味着单击标签也会切换复选框

但是对于单个视图模型字段有多个复选框的情况又如何呢?(例如,可能每个复选框代表一个整数值内的一位。)或者,更好的是,单选按钮,其中始终有多个选项与同一字段关联

在这些情况下,上面的代码似乎有问题。不是所有元素都与同一字段相关联,就是呈现具有相同ID的多个元素

我已经研究了一段时间了。我找到了许多解决办法;然而,它们似乎要么没有可点击的标签,要么需要大量定制和/或非标准编码。有些人完全避免使用RadioButtonOn/Labelf,而是选择对原始HTML进行编码

对原始HTML进行编码很好,但是MVC的设计者难道没有预料到我们可能需要为同一个字段使用多个单选按钮吗?如果他们这样做了,他们打算如何对其进行编码

编辑:

经过进一步研究,下面的代码是我发现的编写单选按钮代码的最好方法。这段代码假设我已经为我的每个单选选项定义了一个枚举

@Html.RadioButtonFor(m => m.Gender, Gender.Male, new { id = "gender-male" })
@Html.LabelFor(m => m.Gender, Gender.Male.ToString(), new { @for = "gender-male" })
@Html.RadioButtonFor(m => m.Gender, Gender.Female, new { id = "gender-female" })
@Html.LabelFor(m => m.Gender, Gender.Female.ToString(), new { @for = "gender-female" })
也许这是我所能期望的最好的,但它仍然让我有点困扰

  • 为什么像ID这样的基本东西需要如此多的定制?同样,难道微软没有预料到我们会想要多个单选按钮与同一个字段关联吗

  • 如果枚举名称与我想要的单选按钮标签的描述不同,这种方法似乎不支持字段属性,例如
    [Display(name=”“)]


  • (我想多个复选框的正确处理将推迟到另一个问题。)

    好的,让我们做一些研究。首先,通过单击标签切换复选框/收音机不需要唯一的id。实际上你根本不需要身份证!您只需将输入内容包装在
    标记中:

    <label>
        <input type="radio" name="radio" value="1" /> Radio 1   
    </label>
    
    该死!我刚刚复制了粘贴的教程模型o_o。我们现在想要的是获得用户的性别,所以我们添加了一个
    gender
    enum:

    public enum Gender
    {
        Iamparanoic = 0,
    
        Male = 1,
    
        Female = 2,
    }
    
    并将
    Gender
    字段的
    Gender
    类型添加到我们的模型中(希望c#有一个
    Gender
    访问修饰符!)

    现在,是时候使用一些asp.net魔法并编写我们的html帮助程序了:

    public static MvcHtmlString RadioButtonsListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
    {
        var sb = new StringBuilder();
        sb.Append("<ul>"); //we want it to look cool, dont' we?
        foreach (var value in Enum.GetValues(typeof(TEnum)))
        {
            var radio = htmlHelper.RadioButtonFor(expression, value).ToHtmlString(); //you can generage any id and pass it to helper, or use a tagbuilder
    
            sb.AppendFormat(
                "<li><label>{0} {1}</label></li>",
                radio,
                ((Enum)value).GetEnumName() //instead of it you can grab e.g. Display/Description attribute value or w/e else
            );
        }
        sb.Append("</ul");
        return MvcHtmlString.Create(sb.ToString());
    }
    
    真漂亮,不是吗?当然,您可以添加很多自定义项,比如使用独特的mvc样式id呈现单选按钮、各种html属性等。但这只是一个示例,非常正确

    接下来,我们还要呈现checkboxlist

    public static MvcHtmlString CheckBoxListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, IDictionary<string, object> htmlAttributes = null)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var enumValue = Convert.ToInt32(metadata.Model);
    
        var sb = new StringBuilder();
        foreach (var value in Enum.GetValues(typeof (TEnum)))
        {
            var val = Convert.ToInt32(value);
            var checkbox = new TagBuilder("input");
    
            checkbox.MergeAttribute("type", "checkbox");
            checkbox.MergeAttribute("value", value.ToString());
            checkbox.MergeAttribute("name", htmlHelper.NameFor(expression).ToString());
    
            if ((enumValue & val) == val)
                checkbox.MergeAttribute("checked", "checked");
            if (htmlAttributes != null)
                checkbox.MergeAttributes(htmlAttributes);
    
            var label = new TagBuilder("label") { InnerHtml = checkbox + ((Enum)value).GetEnumName() };
    
            sb.Append(label);
            sb.Append("<br/>");
        }
        return new MvcHtmlString(sb.ToString());
    }
    

    顺便说一句,它只适用于标记有
    标志
    属性的枚举,当然,您在模型绑定方面会遇到问题-它需要自定义绑定器。但这是另一个问题,我希望能回答:)

    在我看来,我认为微软方面无法采取任何措施来处理您正在谈论的案件

    从Html代码开始,如何在Html中显示多个单选按钮

    <form action="">
    <input type="radio" name="sex" value="male">Male<br>
    <input type="radio" name="sex" value="female">Female
    </form>
    
    
    男性
    女性
    上面是我从中带来的样本

    如果要通过单击标签来切换单选按钮,可以通过两种方式在html中实现

    第一种方法是在标签中使用for标记

    <input type="radio" id="myId" name="MyName" value="MyValue" />
    <label for="myId">Display Name</label>
    
    
    显示名称
    
    第二种方法是将无线电输入放在标签内

    <label>
       <input type="radio" id="myId" name="MyName" value="MyValue"/> 
       Display Name
    </label>
    
    
    显示名称
    
    正如你所看到的,当你点击标签时,它的标签组合可以让单选按钮切换,我认为微软保持了它的简单性和灵活性,让开发者可以选择做什么以及他喜欢的方式

    现在,为了在Mvc中获得相同的结果,您可以在上面提到的这两种方法中的一种中硬编码每个单选按钮,或者更简单地编写自己的Mvc Html扩展,我推荐第二种方法


    希望这将对您有所帮助

    在我看来,
    RadioButtonFor
    应该有像
    DropDownListFor
    这样的重载,在这里我可以传递一个项目列表,并且每个项目的单选按钮都会生成可单击的标签。@th1rdey3:我不确定DropDownListFor。也许是RadioButtonListFor?而且,如果您想使用第三方选项。但我不明白为什么微软不认为这是必要的。现在你一个人在说话。。。关于这个问题,你找到的解决方案,我想是。。。与此同时,只是指着阿米罗塞因梅尔瓦齐删除了他所有的评论。对了。@JonathanWood顺便说一句,你在1月1日凌晨2:56做了什么??你为什么不庆祝新年呢?:)加1表示在
    元素中包含复选框,这不需要唯一的ID。我熟悉这种方法,但不建议阅读它。然而,现在研究它,似乎这两种方法都同样有效。关于定制HtmlHelper,我已经编写了一个非常复杂的工具,正如我在这里的讨论中所指出的。Mine还将对枚举值使用任何[Description]属性(如果有)。我的复选框版本支持最初选择的值的列表。我仍然完全不知道为什么MVC中没有一些基本的支持。事实上,即使使用在
    元素中包装
    @Html.CheckBoxFor()
    的技术也是无效的,因为它将生成重复的ID。“即使这样做行得通,那也是不好的形式。”乔纳桑伍德实际上我已经注意到这只是一个样本。希望您能够了解如何使用模型元数据和当前枚举值生成唯一id?此外,您还可以使用htmlattributes、包装/或不包装到
    ul
    来定制所需的帮助程序,为什么MVC中没有对它的基本支持?因为大多数人都不喜欢
    @Html.CheckBoxListForEnum(m => m.Gender)
    
    <form action="">
    <input type="radio" name="sex" value="male">Male<br>
    <input type="radio" name="sex" value="female">Female
    </form>
    
    <input type="radio" id="myId" name="MyName" value="MyValue" />
    <label for="myId">Display Name</label>
    
    <label>
       <input type="radio" id="myId" name="MyName" value="MyValue"/> 
       Display Name
    </label>