【问题标题】:Using CheckBoxFor in a form在表单中使用 CheckBoxFor
【发布时间】:2015-01-24 23:53:52
【问题描述】:

我在一个视图中有以下表格:

@using (Html.BeginForm("Subscriptions", "Group", new { id = Model.Id, slug = Model.Slug,  Groups = Model.Groups,  Names = Model.SelectedNames, SelectedMemberEmail = Model.SelectedMember.EmailAddress, WhichView = "Subscriptions", }, FormMethod.Post))
   {
     <div id="communitygroupsedit" class="list-unstyled">
       @for (var x = 0; x < Model.Groups.Count; x++)
          {
             if (Model.Groups[x].Name == "All members")
               {
                  Model.Groups[x].AdminOnly = true;
               }
            string adminTest = (Model.Groups[x].AdminOnly && !Model.IsUserAdministrator) ? "disabled=\"disabled\"" : string.Empty;
            string checktest = Model.Groups[x].IsMember ? "checked=\"checked\"" : string.Empty;

             <p>
               @Html.CheckBoxFor(m => m.Groups[x].IsMember, new { @adminTest @checktest})
               @Html.Raw(Model.Groups[x].Name + " - " + Model.Groups[x].Description)
               @if (adminTest == "disabled=\"disabled\"" && !Model.IsUserAdministrator && checktest == "checked=\"checked\"")
                {
                    Model.SelectedNames.Add(Model.Groups[x].Name);
                }                         
             </p>
      }
       </div>
     if (Model.Groups.Count > 0)
     {
         @Html.SubmitButton("Update groups", false, new { @class = "btn btn-primary" });
      }

问题在于,在控制器中,“组”列表对象为空,而在视图中,满足条件时复选框不会被禁用。此外, selectednames 属性也没有根据我的需要填充“名称”列表。我在这个表单中做错了什么?

【问题讨论】:

  • 恕我直言,您在视图中进行了如此多的处理,很难理解发生了什么。像 adminTest 和 checktest 这样的东西真的应该在控制器中。

标签: c# html asp.net-mvc forms checkbox


【解决方案1】:

我很高兴地说我终于让它工作了。斯蒂芬您的帖子说明我不了解表单应该如何工作,因为我认为您可以将任何旧值从那里传递给控制器​​。不幸的是,您的解决方案对我不起作用,因为如果是“adminOnly”复选框并且您的代码根本不会显示它,我仍然希望将复选框显示为只读状态。

我解决了 checkboxfor 返回 false 的问题,如果它被禁用,只需按照我想要的方式呈现一个复选框,然后使用 hiddenfor 返回框的状态。
您问的另一件事是 if(groups.count> 0) ..show 提交按钮有什么意义。这是因为如果没有组,我不希望呈现提交按钮。

我觉得我从这个问题中学到了很多东西,所以非常感谢 Stephen 的所有帮助。

这是我想出的:

 @using (Html.BeginForm("Subscriptions", "Group", FormMethod.Post))
     {
       <div id="communitygroupsedit" class="list-unstyled">
          <p> @if (Model.Groups[x].AdminOnly)
                {
                  string adminTest = (Model.Groups[x].AdminOnly && !Model.IsUserAdministrator) ? "disabled=\"disabled\"" : string.Empty;
                  string checktest = Model.Groups[x].IsMember ? "checked=\"checked\"" : string.Empty;
                  <input type="checkbox" @adminTest @checktest />

                  @Html.HiddenFor(m => m.Groups[x].IsMember)
                  @Html.HiddenFor(m => m.Groups[x].Name)
                  @Html.HiddenFor(m => m.Groups[x].AdminOnly)
               }
              else
                 {
                   @Html.CheckBoxFor(m => m.Groups[x].IsMember)
                @Html.HiddenFor(m => m.Groups[x].Name)
                 @Html.HiddenFor(m => m.Groups[x].AdminOnly)
              }
              @Html.Raw(Model.Groups[x].Name + " - " + Model.Groups[x].Description)
                                             </p>
               }
             </div>
             if (Model.Groups.Count > 0)
           {
           @Html.SubmitButton("Update groups", false, new { @class = "btn btn-primary" });
           }
        }

在控制器中:

 List<string> Names = new List<string>();
 foreach (var group in input.Groups)
   {
     if (group.IsMember)
     Names.Add(group.Name);
   }

...写入数据库

【讨论】:

  • 您仍然没有获得 MVC 或 Http。没有只读复选框之类的东西 - 只需显示“是”或“否”(或类似的)。您不应为未更改的数据呈现隐藏输入。您打开自己的过度发布攻击,并向客户端发送大量数据,然后再次原封不动地返回只会降低性能 - 如果需要,只需使用 POST 方法从数据库中获取它。至于if(groups.count&gt; 0) - 如果没有要显示的组,你为什么要首先返回视图,所以if 毫无意义。
【解决方案2】:

我在这个表单中做错了什么? 一切!

至于为什么你没有收到SelectedNames,你没有为它渲染任何控件,所以怎么回帖

如果您查看&lt;form&gt; 标记的action 属性,应该很明显。它会有类似的东西

<form action="/Group/Subscriptions.....?Names=System.Collections.Generic.List%601%5BYourAssembly.YourModelName%5D" ....>

所以当您发布表单时,属性SelectedNames 是一个字符串"System.Collections.Generic.List...",不能绑定到集合。

现在检查 html 中的复选框,你会看到类似(取决于 adminTestchecktest 的值

<input type="checkbox" ... adminTest="" checktest="checked="checked"">

这当然不会设置复选框的disabledchecked 属性。即使您正确操作并且复选框被禁用并选中(true),它也会发回 false 的值(禁用的复选框不会发回,因此 ModelBinder 将绑定为 false,因为相关的隐藏输入),你会得到不正确的数据。

当您使用@Html.CheckBoxFor(m =&gt; m.Groups[x].IsMember) 时,复选框状态是根据IsMember 的值设置的,因此代码string checktest = Model.Groups[x].IsMember ? "checked=\"checked\"" : string.Empty; 不仅错误,而且完全没有意义。

if (Model.Groups.Count &gt; 0) 的意义何在?您正在编辑的唯一内容是Groups,所以如果没有,为什么会显示无法提交的空白表单!

删除所有这些并创建一个视图模型以显示/编辑您想要的内容

查看模型

public class GroupVM
{
  public int ID { get; set; }
  public string DisplayName { get; set; }
  public bool IsMember { get; set; }
}

public class MyModelVM
{
  public int ID {get; set; }
  // any other properties of the model you want to display
  public List<GroupVM> Groups { get; set; }
}

控制器

public ActionResult Group(int ID)
{
  // Get your data model
  ....
  MyModelVM model = new MyModelVM();
  model.Groups = new List<GroupVM>();
  // Populate the collection based on your data model
  foreach(var item in yourDataModel.Groups)
  {
    GroupVM group = new GroupVM();
    // apply you logic here
    if(item.AdminOnly && !item.IsUserAdministrator)
    {
      continue; // no point displaying these
    }
    group.ID = item.ID;
    group.DisplayName = string.Format("{0} - {1}", item.Name, item.Description)
    group.IsMember = item.IsMember;
    model.Groups.Add(group);
  }
  if (model.Groups.Count == 0)
  {
    // ?? is there any point displaying a form?
  }
  return View(model);
}

查看

@model MyModelVM
@using (Html.BeginForm())
{
  for(int i = 0; i < Model.Groups.Count; i++)
  {
    @Html.HiddenFor(m => m.Groups[i].ID)
    @Html.CheckBoxFor(m => m.Groups[i].IsMember)
    @Html.LabelFor(m => m.Groups[i].DisplayName)
  }
  <input type="submit" value="Update groups" />
}

POST 方法

public ActionResult Group(MyModel model)
{
  // The model contains the ID so get the data model from the database
  // and loop model.Groups to update the data model and save
}

【讨论】:

  • 非常感谢斯蒂芬的详细回复。正如您可能已经猜到的,编程对我来说是一个非常新的事物,我经常发现它非常混乱,并且不得不进行大量猜测。我非常期待详细了解您的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多