在ASP.NET MVC 4中获取复选框值


122

我正在开发ASP.NET MVC 4应用程序。这个程序有一个基本形式。我的表单的模型如下所示:

public class MyModel
{
    public string Name { get; set; }
    public bool Remember { get; set; }
}

在我的表单中,我具有以下HTML。

<input id="Name" name="Name" type="text" value="@Model.Name" />
<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
<label for="Remember">&nbsp;Remember Me?</label>

发布表单时,模型中的“记住”值始终为false。但是,模型中的Name属性具有一个值。我已经通过在以下位置设置断点进行了测试:

[HttpPost]
public ActionResult MyAction(MyModel model)
{
  Console.WriteLine(model.Remember.ToString());
}

我不知道。为什么未设置Checkbox值?


它以适当的值发布吗?你能用提琴手检查一下吗?另外,我不知道复选框的值是否/如何转换为布尔值。
shahkalpesh

这将以“打开”或“关闭”形式发布到表单。这显然不正确。我做了一个愚蠢的枚举来避免这种情况。
Yablargo 2015年

@Yablargo,您不需要枚举。只需将value =“ true”添加到输入标签。并使用带有value =“ false”的隐藏项,如下所示。
sympatric greg,2015年

Answers:


213
@Html.EditorFor(x => x.Remember)

将产生:

<input id="Remember" type="checkbox" value="true" name="Remember" />
<input type="hidden" value="false" name="Remember" />

它是如何工作的:

  • 如果checkbox未选中,则表单仅提交hidden值(假)
  • 如果选中,则表单true将为模型的bool属性提交两个字段(false和true)和MVC集

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

如果选中,它将始终发送默认值。


7
嗨,这种行为使我的模型无法通过验证,因为它似乎无法弄清楚如何将[true,false]转换为单个布尔值。您如何解决这个问题?
奥比

@ObiOnuorah您正在使用什么结构?助手还是硬编码的html标记?
webdeveloper

5
Html.EditorFor或Html.CheckBoxFor都给出相同的结果
Obi,

3
如果使用formCollection,则作为结果返回给复选框的字符串为:“ true,false”。您如何解析呢?是Replace()唯一的选择吗?
Jo Smo

7
如果您要手动添加自己的复选框,则关键部分是该应设置为“ true”,否则表单返回的默认值将为“ on”,而“ on”不能绑定到布尔值这需要是非。(您可能会看到一个验证错误,表明“ on”值对于field无效。)
Greg

69

由于您正在使用Model.Name来设置值。我假设您正在将一个空的视图模型传递给View。

因此,Remember的值为false,并将checkbox元素的值设置为false。这意味着,当您随后选择复选框时,您将在表单中发布值“ false”。当您不选择它时,它不会被发布,因此模型默认为false。这就是在两种情况下都看到错误值的原因。

仅当您选中选择框时,才传递该值。在Mvc中使用复选框

@Html.CheckBoxFor(x => x.Remember)

或者如果您不想将模型绑定到视图。

@Html.CheckBox("Remember")

Mvc对隐藏字段进行了一些魔术处理,以在未选择值时保留值。

编辑,如果您确实不愿意这样做并且想自己生成元素,则可以这样做。

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked=\"checked\"" : "") />

2
@Html.CheckboxFor代码实际上应该是@Html.CheckBoxFor
fujiiface '16

很快,您将如何使用@(Model.Remember ? "checked=\"checked\"" : "")单选按钮?还是不可能
Izzy

使用该选项,您直接操作HTML,一个单选按钮为type="radio",选择要在HTML中选择的按钮与上面的相同checked="checked"。区别在于您将有多个<input />具有相同名称的元素。您需要确定将多余的HTML应用于哪一个。
Dan Saltmer '17

@Html.CheckBoxFor(x => x.Remember)这对我
有用


5

代替

 <input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

用:

 @Html.EditorFor(x => x.Remember)

这将为您提供一个专门用于记住的复选框


4

好的,该复选框有点奇怪。当您使用Html帮助程序时,它会在标记上生成两个复选框输入,如果选中,则它们都会作为IEnumerable的名称/值对传递。

如果未在标记上对其进行检查,则仅将其传递给值为false的隐藏输入。

因此,例如,您在标记上具有:

      @Html.CheckBox("Chbxs") 

并在控制器操作中(确保名称与控制器上的复选框参数名称匹配):

      public ActionResult Index(string param1, string param2,
      string param3, IEnumerable<bool> Chbxs)

然后,您可以在控制器中执行以下操作:

      if (Chbxs != null && Chbxs.Count() == 2)
        {
            checkBoxOnMarkup = true;
        }
        else
        {
            checkBoxOnMarkup = false;
        }

我知道这不是一个很好的解决方案。希望这里有人可以给一些指点。


3

要将表单中的复选框返回的值转换为布尔值属性,我在自定义ModelBinder中使用了ValueProviderResult的内建转换器。

ValueProviderResult cbValue = bindingContext.ValueProvider.GetValue("CheckBoxName");
bool value = (bool)cbValue.ConvertTo(typeof(bool));

3

如果使用FormCollection而不是模型,则分配可以很简单:

MyModel.Remember = fields["Remember"] != "false";

2

我遇到了类似的问题,并且能够通过使用复选框,hiddenfor和小JQuery来获取复选框的值,如下所示:

@Html.CheckBox("isPreferred", Model.IsPreferred)
@Html.HiddenFor(m => m.IsPreferred)

<script>

    $("#isPreferred").change(function () {

        $("#IsPreferred").val($("#isPreferred").val());

    })

</script>

2

这是一个主要的痛苦,并且感觉应该更简单。这是我的设置和解决方案。

我正在使用以下HTML帮助器:

@Html.CheckBoxFor(model => model.ActiveFlag)

然后,在控制器中,我正在检查表单集合并进行相应的处理:

bool activeFlag = collection["ActiveFlag"] == "false" ? false : true;
[modelObject].ActiveFlag = activeFlag;

同意,我把它做的更短,因为user.IsActive = fc["IsActive"] != "false";我仍然觉得比较不干净。
WildJoe

1

我只是碰到了这个(我不敢相信它不会打开/关闭!)

无论如何!

<input type="checkbox" name="checked" />

将发布值“开”或“关”。

WONT绑定到布尔值,但是您可以执行此愚蠢的解决方法!

 public class MyViewModel
 {
     /// <summary>
     /// This is a really dumb hack, because the form post sends "on" / "off"
     /// </summary>                    
     public enum Checkbox
     {
        on = 1,
        off = 0
     }
     public string Name { get; set; }
     public Checkbox Checked { get; set; }
}

1
@Html.EditorFor(x => x.ShowComment)


$(function () {
        // set default value to control on document ready instead of 'on'/'off' 
        $("input[type='checkbox'][name='ShowComment']").val(@Model.ShowComment.ToString().ToLower());
    });

    $("#ShowComment").change(function() {
        // this block sets value to checkbox control for "true" / "false"

        var chkVal = $("input[type='checkbox'][name='ShowComment']").val();
        if (chkVal == 'false') $("input[type='checkbox'][name='ShowComment']").val(true);
        else $("input[type='checkbox'][name='ShowComment']").val(false);

    });

3
您好Surendran,欢迎来到Stack Overflow。当包含代码时,请对其进行格式化以提高可读性。但是更重要的是,解释所包含的代码为何能够解决OP的问题至关重要。
Alex A.

1

对于使用Model的MVC。模型:

public class UserInfo
{
    public string UserID { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
}

HTML:

<input type="checkbox" value="true" id="checkbox1" name="RememberMe" checked="@Model.RememberMe"/>
<label for="checkbox1"></label>

在[HttpPost]函数中,我们可以获取其属性。

[HttpPost]
public ActionResult Login(UserInfo user)
{
   //...
   return View(user);
}

1

如果您真的想使用纯HTML(无论出于何种原因)而不是使用内置的HtmlHelper扩展,则可以采用这种方式。

代替

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

尝试使用

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked" : "") />

HTML中的复选框输入有效,因此,在选中它们时,它们将发送值,而在未选中它们时,它们将不发送任何内容(这将导致ASP.NET MVC退回到默认值。字段false)。另外,HTML中复选框的值不仅可以是true / false,还可以是任何值,因此,如果您确实需要,甚至可以为模型中的字符串字段使用复选框。

如果您使用内置功能Html.RenderCheckbox,则它实际上输出两个输入:复选框和一个隐藏字段,以便在取消选中复选框时发送错误值(不只是什么)。这可能会导致一些意外情况,例如:


0

对于具有相同名称的多个复选框...删除不必要的false的代码:

List<string> d_taxe1 = new List<string>(Request.Form.GetValues("taxe1"));
d_taxe1 = form_checkbox.RemoveExtraFalseFromCheckbox(d_taxe1);

功能

public class form_checkbox
{

    public static List<string> RemoveExtraFalseFromCheckbox(List<string> val)
    {
        List<string> d_taxe1_list = new List<string>(val);

        int y = 0;

        foreach (string cbox in val)
        {

            if (val[y] == "false")
            {
                if (y > 0)
                {
                    if (val[y - 1] == "true")
                    {
                        d_taxe1_list[y] = "remove";
                    }
                }

            }

            y++;
        }

        val = new List<string>(d_taxe1_list);

        foreach (var del in d_taxe1_list)
            if (del == "remove") val.Remove(del);

        return val;

    }      



}

用它 :

int x = 0;
foreach (var detail in d_prix){
factured.taxe1 = (d_taxe1[x] == "true") ? true : false;
x++;
}

0
public ActionResult Index(string username, string password, string rememberMe)
{
   if (!string.IsNullOrEmpty(username))
   {
      bool remember = bool.Parse(rememberMe);
      //...
   }
   return View();
}

0

修改记住这样

public class MyModel
{
    public string Name { get; set; }
    public bool? Remember { get; set; }
}

在控制器中使用可为null的布尔值,然后在null上回退为false,如下所示

[HttpPost]
public ActionResult MyAction(MyModel model)
{
    model.Remember = model.Remember ?? false;
    Console.WriteLine(model.Remember.ToString());
}


0

我通读了其他答案,但并没有完全起作用-所以这是我最终得到的解决方案。

我的表单使用Html.EditorFor(e => e.Property)来生成复选框,并FormCollection在控制器中使用它在控制器中传递字符串值'true,false'

当我处理结果时,我使用一个循环来循环遍历它们-我还使用一个InfoProperty实例来表示从表单评估的当前模型值。

因此,我只是检查返回的字符串是否以单词开头'true',然后将boolean变量设置为true并将其传递给返回模型。

if (KeyName.EndsWith("OnOff"))
{
    // set on/off flags value to the model instance
    bool keyTrueFalse = false;
    if(values[KeyName].StartsWith("true"))
    {
        keyTrueFalse = true;
    }
    infoProperty.SetValue(processedInfo, keyTrueFalse);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.