如何在ASP中处理复选框。NET MVC窗体?

注意:这个问题已经超过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更新的。

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

238278 次浏览

这是我一直在做的。

观点:


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

控制器:


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


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

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

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

超文本标记语言CheckBox做了一些奇怪的事情——如果你在结果页面上查看源代码,你会看到每个复选框旁边都生成了<input type="hidden" />,这解释了你看到的每个表单元素的“true false”值。

试试这个,它肯定能在ASP上工作。NET MVC Beta版,因为我刚刚尝试过。

把它放在视图中,而不是使用Html.CheckBox():

<% using (Html.BeginForm("ShowData", "Home")) {  %>
<% foreach (var o in ViewData.Model) { %>
<input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
<%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>

你的复选框都被称为selectedObjects,每个复选框的value是对应对象的GUID。

然后发布到下面的控制器动作(或做一些有用的事情而不是Response.Write())

public ActionResult ShowData(Guid[] selectedObjects) {
foreach (Guid guid in selectedObjects) {
Response.Write(guid.ToString());
}
Response.End();
return (new EmptyResult());
}

这个例子只会写你选中的方块的guid;ASP。NET MVC将选中复选框的GUID值映射到Guid[] selectedObjects参数中,甚至解析来自请求的字符串。将集合形成实例化的GUID对象,我认为这是相当不错的。

HtmlHelper添加了一个隐藏的输入来通知控制器未检查状态。 因此,要获得正确的检查状态:

bool bChecked = form[key].Contains("true");

您还应该使用<label for="checkbox1">Checkbox 1</label>,因为这样人们就可以单击标签文本以及复选框本身。它也更容易设置样式,至少在IE中,当你通过页面的控件时,它会被突出显示。

<%= Html.CheckBox("cbNewColors", true) %><label for="cbNewColors">New colors</label>

这不仅仅是一件‘哦,我可以做到’的事情。这是一个显著的用户体验增强。即使不是所有用户都知道他们可以点击标签,很多人也会。

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

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

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

.日志含义

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

这个问题也出现在1.0版中。Html.Checkbox()导致添加另一个隐藏字段,其名称/id与原始复选框相同。当我尝试使用document.GetElemtentsByName()加载复选框数组时,您可以猜到事情是如何变得混乱的。这很奇怪。

它们似乎选择只读取第一个值,所以当选中复选框时,这是“true”,而当只包括隐藏值时,这是“false”。这很容易用这样的代码获取:

model.Property = collection["ElementId"].ToLower().StartsWith("true");

我还想指出,您可以为每个复选框命名一个不同的名称,并将该名称作为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) {
...
}

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

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

伟大的发现!!我非常感谢。为了进一步扩展,这种技术还可以与视图模型方法完美结合。MVC太酷了,它足够聪明,可以将一组guid绑定到与绑定到视图的Model对象同名的属性上。例子:

视图模型:

public class SampleViewModel
{
public IList<SampleObject> SampleObjectList { get; set; }
public Guid[] SelectedObjectIds { get; set; }


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

观点:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View</h2>
<table>
<thead>
<tr>
<th>Checked</th>
<th>Object Name</th>
</tr>
</thead>
<% using (Html.BeginForm()) %>
<%{%>
<tbody>
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
</tbody>
</table>
<input type="submit" value="Submit" />
<%}%>

控制器:

    [AcceptVerbs(HttpVerbs.Get)]
public ActionResult SampleView(Guid id)
{
//Object to pass any input objects to the View Model Builder
BuilderIO viewModelBuilderInput = new BuilderIO();


//The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects
SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput);


return View("SampleView", viewModel);
}


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SampleView(SampleViewModel viewModel)
{
// The array of Guids successfully bound to the SelectedObjectIds property of the View Model!
return View();
}

任何熟悉视图模型哲学的人都会感到高兴,这就像一个冠军!

<input type = "checkbox" name = "checkbox1" /> <label> Check to say hi.</label>

来自控制器:

    [AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection fc)
{


var s = fc["checkbox1"];


if (s == "on")
{
string x = "Hi";
}
}

这是我在使用Html.CheckBox(…

Replace("true,false","true").Split(',')

有4个框选中,未选中,未选中,选中它转动 真的,假的,假的,假的,真的,假的 成 真的,假的,假的,真的。

像这样的怎么样?

bool isChecked = false;
if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false)
ModelState.AddModelError(”chkHuman”, “Nice try.”);

我的解决方案是:

<input type="checkbox"  id="IsNew-checkbox"  checked="checked" />
<input type="hidden"  id="IsNew" name="IsNew" value="true"  />
<script language="javascript" type="text/javascript" >
$('#IsNew-checkbox').click(function () {
if ($('#IsNew-checkbox').is(':checked')) {
$('#IsNew').val('true');
} else {
$('#IsNew').val('false');
}
});
</script>

更多信息请点击: http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized-as-a-valid-boolean/ < / p >

当使用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作为数组返回。

只需在$(document).ready上执行此操作:

$('input:hidden').each(function(el) {
var that = $(this)[0];
if(that.id.length < 1 ) {


console.log(that.id);
that.parentElement.removeChild(that);


}
});

我很惊讶这些答案中没有一个使用内置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="selectedProducts" value="@item.ProductId" />@item.Name

然后在提交时抓取复选框的值并保存在int数组中。 然后是相应的LinQ函数。就是这样. . < / p >
[HttpPost]
public ActionResult Checkbox(int[] selectedObjects)
{
var selected = from x in selectedObjects
from y in db
where y.ObjectId == x
select y;


return View(selected);
}

从我所能收集到的,模型不想猜测是否checked = true或false,我通过在提交表单之前使用jQuery在复选框元素上设置一个值属性来解决这个问题:

 $('input[type="checkbox"]').each(function () {
$(this).attr('value', $(this).is(':checked'));
});

这样,您就不需要一个隐藏元素来存储复选框的值。

我知道这个问题是在MVC3还没有出来的时候写的,但是对于任何遇到这个问题并且正在使用MVC3的人来说,您可能想要“正确”的方法来做这件事。

而我认为整个

Contains("true");

事情是伟大的和干净的,并适用于所有MVC版本,问题是,它没有考虑文化(如果它真的很重要的情况下bool)。

至少在MVC3中,计算bool值的“正确”方法是使用ValueProvider。

var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool));

当我编辑权限时,我在客户的一个网站上这样做:

var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList();
var allPermissions = new List<KeyValuePair<int, bool>>();


foreach (var key in allPermissionsBase)
{
// Try to parse the key as int
int keyAsInt;
int.TryParse(key.Replace("permission_", ""), out keyAsInt);


// Try to get the value as bool
var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool));
}

现在,它的美妙之处在于,你可以将它用于任何简单的类型,甚至根据文化(想想钱,小数等)它都是正确的。

ValueProvider是当你像这样形成action时使用的:

public ActionResult UpdatePermissions(bool permission_1, bool permission_2)

但是当您尝试动态地构建这些列表并检查值时,您永远不会在编译时知道Id,因此您必须动态地处理它们。

我有几乎相同的问题,但我的控制器的返回值被其他值阻塞。

找到了一个简单的解决方案,但它似乎有点粗糙。

尝试在你的控制器中输入Viewbag.,现在你给它一个像Viewbag.Checkbool这样的名字

现在切换到视图并尝试使用@Viewbag.Checkbool,你将从控制器中获得值。

我的控制器参数是这样的:

public ActionResult Anzeigen(int productid = 90, bool islive = true)

我的复选框会像这样更新:

<input id="isLive" type="checkbox" checked="@ViewBag.Value" ONCLICK="window.location.href = '/MixCategory/Anzeigen?isLive=' + isLive.checked.toString()" />

使用@mmacaulay,我得到了bool:

// MVC Work around for checkboxes.
bool active = (Request.Form["active"] == "on");
如果检查< p > Active = true

< p >如果不加以控制 Active = false

与nautic20的答案相同,只是简单地使用MVC默认模型绑定复选框列表与ViewModel中string/int/enum的集合属性同名。就是这样。

但有一个问题需要指出。在每个复选框组件中,不应该在其中放入“Id”,这会影响MVC模型绑定。

下面的代码将用于模型绑定:

 <% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>

下面的代码将不会绑定到模型(这里的区别是为每个复选框分配id)

<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" id="[some unique key]" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>