CheckBox的MV3重复查询字符串值(true,false表示布尔值)

时间:2011-11-14 09:33:53

标签: asp.net-mvc-3 razor query-string

我创建了一个相当直接的页面,其中包含一个复选框:

@using (Html.BeginForm("MyController", "MyAction", FormMethod.Get))
{
  @Html.CheckBoxFor(x => x.MyCheckBox)
  <input type="submit" value="Go!" />      
}

使用两次MyCheckBox值填充URL!?就这样:

MyAction?MyCheckBox=true&MyCheckBox=false

如果复选框为true,则仅复制值。如果设置为false,它将仅在查询字符串中出现一次。

上面的代码是简化的,因为我有一些下拉菜单和表单上的文本框,工作正常。我不认为我从这个问题中遗漏的代码有什么不寻常之处。

有没有人遇到类似的问题,查询字符串参数是否重复?

4 个答案:

答案 0 :(得分:15)

此行为是由复选框控件设计的。如果未选中,则标准HTML复选框控件不会传递任何值。这是不直观的。相反,ASP.Net复选框控件有2个元素,标准控件是可见的,还有一个值为'False'的隐藏控件。

因此,如果未选中该复选框,则会传递一个值:False 如果选中,则会有两个值TrueFalse。因此,您需要使用以下代码检查代码的有效性:

bool checkboxChecked = Request.QueryString["MyCheckBox"].Contains("True");

答案 1 :(得分:3)

接受的答案是正确的,但在我最近的一次开发中,MVC行为具有误导性。

MVC Html.CheckBox(...)Html.CheckBoxFor(...)使用与复选框控件相同的ID生成'type = hidden'的额外输入,从而导致重复的URL参数。我通过简单地包括所需的标记来解决这个问题,如下所示:

@if(checkTrue){
    <input type="checkbox" id="MyCheckBox" name="MyCheckbox" checked="checked">
}else{
    <input type="checkbox" id="MyCheckBox" name="MyCheckbox">
}

最好用帮助器代替MVC代码,以便封装值检查。

作为我的应用程序的一部分,控制器使用帮助程序使用表单注入和链接注入来维护查询参数集,以便在单击以在同一控制器范围内导航时保留状态(例如,分页/过滤控件)。作为此功能的结果,如果使用标准MVC帮助程序,则复选框元素始终设置为false。我注意到这是一件好事,并没有浪费太多时间在这个bug上。

答案 2 :(得分:1)

在我的模型中,我有一组复选框,如下所示:

public class PrerequisitesViewModel
{
    public List<StudentPrerequisiteStatusViewModel> PrerequisiteStatuses { get; set; }
}

public class StudentPrerequisiteStatusViewModel
{
    public long Id { get; set; }

    public string Name { get; set; }

    public bool IsSelected { get; set; }
}

为了使所有内容都能正确绑定,我必须实际转换查询字符串中的值并使用以下代码手动解析它们:

// fix for how MVC binds checkboxes... it send "true,false" instead of just true, so we need to just get the true
for (int i = 0; i < model.PrerequisiteStatuses.Count(); i++)
{
    model.PrerequisiteStatuses[i].IsSelected = bool.Parse((Request.QueryString[$"PrerequisiteStatuses[{i}].IsSelected"] ?? "false").Split(',')[0]);
}

唉,它有效,但我无法相信这在MVC中是必要的!希望其他人知道更好的解决方案。

答案 3 :(得分:1)

我使用@ Html.HiddenFor

解决了此问题
<input id="checkboxId" type="checkbox" value="true" onchange="changeCheckboxValue()">
@Html.HiddenFor(m => m.MyCheckBox, new { @id = "hiddenId" } )

<script>
  function changeCheckboxValue() {
    document.getElementById("checkboxId").value = document.getElementById("hiddenId").checked;
  }
</script>