全部,请清除我对模型绑定如何与IEnumerables和编辑模板一起工作的困惑。
我有一个视图,Approve.cshtml
@model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th>
Name
</th>
</tr>
@Html.EditorForModel()
</table>
模型,Approve.cs
public class Approve
{
public string Name { get;set;}
public string Role { get; set; }
}
编辑模板
@model MvcWebsite.Models.Approve
@using (Html.BeginForm("Approve", "Registration", FormMethod.Post))
{
<tr>
<td>
@Html.HiddenFor(m => m.Name)
@Html.EditorFor(m => m.Role)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
这一切都很好,很好。它呈现以下输出。
<input name="[0].Name" type="hidden" value="" />
....
但是,在我的Controller中,我似乎无法接收模型(绑定)的值。
[HttpPost]
public ActionResult Approve(Approve approveModel)
{
.... approveModel has all default values
}
有人能说清楚我在做错了吗?我缩写代码,我使用编辑模板与我的模型中的其他EditorFor和HiddenFor字段...
编辑:我基本上有一个表格布局,每个都有用户名,一个文本框,我可以输入他们的角色(用户或管理员),然后是一个提交给我的控制器的批准按钮。因此我想只返回一个Approve对象。我可以将整个IEnumerable返回给我的Controller,但是如果我这样做,我怎么知道哪个项目是我点击批准按钮(提交)的那个?
编辑: 所以我修改了代码,以便我有一个单独的表单围绕我的整个View Approve.cshtml
@model IEnumerable<MvcWebsite.Models.Approve>
@using (Html.BeginForm("Approve", "Program", FormMethod.Post))
{
<table>
<tr>
<th>
Name
</th>
</tr>
@Html.EditorForModel()
</table>
}
然后将控制器更改为
[HttpPost]
public ActionResult Approve(IEnumerable<Approve> approvals)
{
// ???????????????????????
}
现在我还不清楚如何知道我点击哪一行批准。我知道还有其他方法可以完成这项任务(创建一个复选框以批准,批准任何检查,等等)但是,我需要能够单击一个按钮,只保存1行回数据库,无论用户输入信息到其他行。将IEnumerable包装在其自己的模型(即AllApprovals)中,然后将辅助属性添加到该父模型(SelectedIndex等)是否更好?如果这是采取的方法,那么如何在单击“批准”按钮后设置SelectedIndex?这仍然是jquery魔术还是有正确的MVC方法来实现这一目标? Jquery魔术对我来说似乎非常虚伪?
编辑:根据Brian的回答,这是我的决定。仍然感觉不太对劲,但它确实有效!查看
@model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th>
Name
</th>
</tr>
@Html.EditorForModel()
</table>
编辑模板
@using (Html.BeginForm("Approve", "Registration", FormMethod.Post))
{
<tr>
<td>
@Html.HiddenFor(m => m.Name)
@Html.EditorFor(m => m.Role)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
控制器
[HttpPost]
public ActionResult Approve([Bind(Prefix="approval")]Approve approval) {
// WORKS!
}
答案 0 :(得分:2)
由于您一次只更改一个,我认为以下内容比尝试在控制器上找出哪些值已更改,或添加已更改的属性并通过javascript设置更容易。
将Approve.cshtml更改为
@model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th colspan=2>
Name
</th>
</tr>
@foreach(var user in Model){
@using (Html.BeginForm("Approve", "Registration", FormMethod.Post)) {
<tr>
<td>
@Html.EditorFor(m => user)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
}
</table>
将Approve
编辑器模板更改为
@Html.HiddenFor(m => m.Name)
@Html.EditorFor(m => m.Role)
答案 1 :(得分:0)
您绑定到单个Approve类,您应该绑定到IEnumerable<Approve>
答案 2 :(得分:0)
Martin是正确的我只想添加更多信息。使用[0]呈现的HTML是模型绑定器查看的特殊语法,并假设您正在使用列表(如果是对象)。由于您的操作方法只有一个Approve类而不是kist,因此您遇到了这个问题。