将布尔值绑定/提交到单选按钮的MVC绑定

13
我在我的模型中有一个空值可接受的布尔值列。现在,在我的视图中(用于编辑),我想将其绑定到两个单选按钮:是和否。如果该值为null,则只需使这两个单选按钮未被选中即可。我该怎么做呢?
谢谢。
4个回答

24

一旦您选择了单选按钮,实际上没有办法取消选择(作为用户)。我建议如果您确实需要三个值的结果,那么您应该有三个单选按钮--是,否,不确定。

<%= Html.LabelFor( m => m.Foo ) %>
<%= Html.RadioButtonFor( m => m.Foo, "true" ) %> Yes
<%= Html.RadioButtonFor( m => m.Foo, "false" ) %> No
<%= Html.RadioButtonFor( m => m.Foo, string.Empty ) %> Don't Care
<%= Html.ValidationMessageFor( m => m.Foo ) %>

1
谢谢 :) 直到今天才想起我的问题,Html.RadioButtonFor 解决了这个问题。 - Xuan Vu
1
我想到了相同的解决方案,但是如果 Foonull,那么 Don't care 单选框就不会被选中...有什么想法吗? - Michal B.
@MichalB。我不确定。它在模型属性(以及值)上使用Convert.ToString()。如果bool?为空,那么应该转换为string.Empty并且按钮应该被选中。 - tvanfosson
是的,不是这样的。我有一个条件来检查值是否为空,在这种情况下,将html属性checked="checked"应用于最后一个单选按钮。否则就不起作用... - Michal B.
虽然这将允许选择新值,RadioButtonFor() 不会从绑定变量中选择当前值。它需要有条件地设置 checked 属性。因此,它不应该成为被接受的答案。 抱歉。 - iCollect.it Ltd
这个解决方案非常符合我的需求!string.Empty 是传递 null 值给控制器的最佳方式。顺便提一下,我在 Razor 中使用了 @string.Empty。 - Devin Prejean

4

虽然我看到这篇帖子有些晚了,但是我有一个解决方案可以处理设置值的问题。这个解决方案使用了编辑器模板。您需要指定编辑器模板名称。我称之为'NullableBool'。

@model bool?

@{

Layout = null;

IDictionary<string, object> yesAttributes = new Dictionary<string, object>();
IDictionary<string, object> noAttributes = new Dictionary<string, object>();
IDictionary<string, object> naAttributes = new Dictionary<string, object>();

if (Model.HasValue)
{
    if (Model.Value)
    {
        yesAttributes.Add("checked", "checked");
    }
    else
    {
        noAttributes.Add("checked", "checked");
    }
}
else
{
    naAttributes.Add("checked", "checked");
}
}

@Html.RadioButtonFor(m => m, "true", yesAttributes) Yes`

@Html.RadioButtonFor(m => m, "false", noAttributes) No`

@Html.RadioButtonFor(m => m, string.Empty, naAttributes) N/A`

3
使用多个 Html.RadioButtonFor(m => m.Foo, "true") 似乎会生成无效的 HTML,因为它们生成具有相同 ID 的控件:
<input **id="Foo"** ... type="radio" value="True">
<input **id="Foo"** ... type="radio" value="False">

我已经通过在HTML中直接创建单选按钮来解决了这个问题:
<input type="radio" name="Foo" value="true" id="Foo_True"
       <%:Html.WriteCheckedIfTrue(Model.Foo.HasValue && Model.Foo.Value)%>/>
       <label for="Foo_True">Yes</label><br/>

<input type="radio" name="Foo" value="false" id="Foo_False" 
       <%:Html.WriteCheckedIfTrue(Model.Foo.HasValue && !Model.Foo.Value)%>/> 
       <label for="Foo_False">No</label><br/>

<input type="radio" name="Foo" value="" id="Foo_Null" 
       <%:Html.WriteCheckedIfTrue(!Model.Foo.HasValue)%>/> 
       <label for="Foo_Null">Don't Care</label>

请确保根据使用的视图模型来命名单选按钮,例如:Model.Filter.HasImage 被命名为 Filter.HasImage 以与模型绑定一起使用

"html helper" 如下所示:

    public static MvcHtmlString WriteCheckedIfTrue(this HtmlHelper htmlHelper, 
                                                   bool validation)
    {
        if(validation)
            return new MvcHtmlString("checked=\"checked\"");

        return new MvcHtmlString(string.Empty);
    }

1
请注意,您可以覆盖助手生成的ID。 - ChadT

1
这是一个解决问题的简便方法。这是一个非常古老的ASP问题。
问题是需要设置checked属性,因为Html.RadioButtonFor不会根据空布尔值(似乎是一个缺陷)选中单选按钮。
同时,将单选按钮放在

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接