注意:这个问题已经超过9年了!

您最好的选择是搜索更新的问题,或者搜索下面的答案,寻找您特定的MVC版本,因为这里的许多答案现在已经过时了。

如果你确实找到了适合你的版本的答案,请确保答案包含了你正在使用的MVC版本。 (原来的问题从下面开始)


这对我来说似乎有点奇怪,但据我所知,这就是你怎么做的。

我有一个对象集合,我希望用户从中选择一个或多个对象。这对我来说是“带复选框的表单”。我的对象没有任何“选定”的概念(它们是通过反序列化wcf调用形成的基本POCO)。所以,我这样做:

public class SampleObject{
  public Guid Id {get;set;}
  public string Name {get;set;}
}

在视图中:

<%
    using (Html.BeginForm())
    {
%>
  <%foreach (var o in ViewData.Model) {%>
    <%=Html.CheckBox(o.Id)%>&nbsp;<%= o.Name %>
  <%}%>
  <input type="submit" value="Submit" />
<%}%>

并且,在控制器中,这是我能看到的唯一方法来找出用户检查了什么对象:

public ActionResult ThisLooksWeird(FormCollection result)
{
  var winnars = from x in result.AllKeys
          where result[x] != "false"
          select x;
  // yadda
}

首先,它很怪异,其次,对于用户选中的那些项,FormCollection将其值列出为“true false”而不仅仅是true。

显然,我遗漏了一些东西。我认为这是基于这样的想法构建的,即在html表单中所作用的集合中的对象是使用UpdateModel()或通过ModelBinder更新的。

但我的对象并不是为此而设置的;这意味着这是唯一的办法吗?还有别的办法吗?


当前回答

我还想指出,您可以为每个复选框命名一个不同的名称,并将该名称作为actionresults参数的一部分。

的例子,

观点:

 <%= Html.CheckBox("Rs232CheckBox", false, new { @id = "rs232" })%>RS-232

 <%= Html.CheckBox("Rs422CheckBox", false, new { @id = "rs422" })%>RS-422

控制器:

public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
    ...
}

视图中的值被传递给操作,因为名称是相同的。

我知道这个解决方案对您的项目不是理想的,但我想我要把这个想法说出来。

其他回答

当使用HtmlHelper的复选框时,我更喜欢使用已发布的复选框表单数据作为数组。我真的不知道为什么,我知道其他方法也有用,但我想我只是更喜欢把逗号分隔的字符串尽可能地当作一个数组。

所以做一个“检查过的”或真实的测试应该是:

//looking for [true],[false]
bool isChecked = form.GetValues(key).Contains("true"); 

做虚假检查会是:

//looking for [false],[false] or [false]
bool isNotChecked = !form.GetValues(key).Contains("true"); 

主要的区别是在返回数组时使用GetValues。

我很惊讶这些答案中没有一个使用内置MVC特性。

我在这里写了一篇关于这个的博客文章,甚至把标签链接到复选框。我使用EditorTemplate文件夹以一种干净和模块化的方式完成这一任务。

你只会在EditorTemplate文件夹中得到一个新文件,如下所示:

@model SampleObject

@Html.CheckBoxFor(m => m.IsChecked)
@Html.HiddenFor(m => m.Id)
@Html.LabelFor(m => m.IsChecked, Model.Id)

在你的实际视图中,不需要循环,只需一行代码:

@Html.EditorFor(x => ViewData.Model)

访问我的博客文章了解更多细节。

这是我一直在做的。

观点:


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

控制器:


var checkBox = Request.Form["applyChanges"];

if (checkBox == "on")
{
...
}

我找到了Html。* helper方法在某些情况下不是很有用,我最好在普通的旧HTML中做它。这是其中之一,另一个想到的是单选按钮。

编辑:这是在预览5,显然是在版本之间的YMMV。

我还想指出,您可以为每个复选框命名一个不同的名称,并将该名称作为actionresults参数的一部分。

的例子,

观点:

 <%= Html.CheckBox("Rs232CheckBox", false, new { @id = "rs232" })%>RS-232

 <%= Html.CheckBox("Rs422CheckBox", false, new { @id = "rs422" })%>RS-422

控制器:

public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
    ...
}

视图中的值被传递给操作,因为名称是相同的。

我知道这个解决方案对您的项目不是理想的,但我想我要把这个想法说出来。

如果你想知道为什么他们把一个隐藏字段与复选框的名称相同,原因如下:

从源代码MVCBetaSource\MVC\src\MvcFutures\ MVC\ ButtonsAndLinkExtensions.cs注释

呈现一个额外的<input type = "隐藏"……/>为复选框。 这解决了以下场景: 未选中的复选框不会被发送 请求。发送隐藏输入 这样就有可能知道 时,页面上出现复选框 请求已提交。

我猜在幕后,他们需要知道这个绑定到控制器动作方法的参数。然后你可以有一个三状态布尔值(绑定到一个可为空的bool参数)。我还没试过,但我希望他们这么做了。