我在视图中有以下表格:
@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" });
}
问题是在控制器中,&#39;群组&#39; list对象为空,在视图中,满足条件时不会禁用复选框。此选择的名称属性也没有填充&#39;名称&#39;列出我需要的。我在这种形式上做错了什么?
答案 0 :(得分:1)
这种形式我做错了什么? 一切!
至于为什么你没有得到SelectedNames
,你没有为它提供任何控制,所以如何回复
如果您查看action
标记的<form>
属性,则应该很明显。它会有类似
<form action="/Group/Subscriptions.....?Names=System.Collections.Generic.List%601%5BYourAssembly.YourModelName%5D" ....>
因此,当您发布表单时,属性SelectedNames
是一个字符串"System.Collections.Generic.List..."
,它不能绑定到集合。
现在检查html的复选框,您会看到类似的内容(取决于adminTest
和checktest
<input type="checkbox" ... adminTest="" checktest="checked="checked"">
当然不会设置复选框的disabled
或checked
属性。即使你做得正确并且复选框已被禁用并选中(true
),它也会回发false
的值(禁用复选框不会回发,因此ModelBinder
会绑定到false因为相关的隐藏输入而且你得到的数据不正确。
当您使用@Html.CheckBoxFor(m => m.Groups[x].IsMember)
时,复选框状态是根据IsMember
的值设置的,因此代码string checktest = Model.Groups[x].IsMember ? "checked=\"checked\"" : string.Empty;
不仅错误,而且完全没有意义。
if (Model.Groups.Count > 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
}
答案 1 :(得分:-1)
我很高兴地说我终于开始工作了。斯蒂芬你的帖子说明我不知道一个表格应该如何工作,因为我认为你可以将任何旧的值从那里传递给控制器。不幸的是,你的解决方案对我来说不起作用,因为我仍然希望在只读状态下显示复选框,如果它是“管理员”的话。复选框和您的代码根本不会显示它。
我解决了复选框的问题,如果只是按照我想要的方式渲染复选框,然后使用hiddenfor来恢复框的状态,则会返回false。
你问的另一件事是if(groups.count&gt; 0)..show提交按钮是什么意思。这是因为如果没有群组,我不希望呈现提交按钮。
我觉得我从这个问题中学到了很多东西,所以非常感谢斯蒂芬的所有帮助。
这就是我提出的:
@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);
}
...写入数据库