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

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


当前回答

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

ViewModel:

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();
    }

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

其他回答

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

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

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

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

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

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

最简单的方法就是……

您可以设置名称和值。

<输入类型=“checkbox”ProductId " - > @item。Name

然后在提交时抓取复选框的值并保存在int数组中。 然后是相应的LinQ函数。就是这样. .

[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);
        }

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

ViewModel:

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();
    }

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

我知道这个问题是在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,因此您必须动态地处理它们。