ASP.Net mvc模型绑定IEnumerable<使用编辑器模板

本文关键字:编辑器 IEnumerable Net mvc 模型 绑定 ASP | 更新日期: 2023-09-27 18:11:52

所有,请澄清我对模型绑定如何与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="" />
        ....

然而,在我的控制器中,我似乎无法接收回模型(绑定)的值。

[HttpPost]
public ActionResult Approve(Approve approveModel)
{
    .... approveModel has all default values
}

有人能阐明我在这里做错了什么?我缩短了代码,我正在使用编辑器模板与其他EditorFor和HiddenFor字段从我的模型…

编辑:我基本上有一个表的布局,每个用户的名字,一个文本框,我可以输入他们的角色(用户或管理员),然后一个批准按钮提交到我的控制器。因此,我希望只返回一个Approve对象。我可以将整个IEnumerable返回给我的Controller,但是如果我这样做了,我怎么知道哪个项是我点击了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等)?如果要采用这种方法,那么在单击Approve按钮后如何设置selecteindex ?这仍然是jquery的魔力还是有一个正确的MVC方式来完成这一点?对我来说,Jquery魔法似乎很粗糙。

编辑:根据布莱恩的回答,这是我的最终结论。还是感觉不太对,但很管用!视图

@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!
}

ASP.Net mvc模型绑定IEnumerable<使用编辑器模板

由于您一次只更改一个,我认为以下操作比试图找出控制器中哪些值发生了变化,或添加更改的属性并通过javascript设置它更容易。

更改批准。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) 

您绑定到单个Approve类,您应该绑定到IEnumerable<Approve>

Martin说得对,我只是想补充一些信息。呈现的带有[0]的HTML是模型绑定器查看的特殊语法,并假设您正在处理一个对象列表。由于您的操作方法只有一个Approve类,而不是一个列表,因此您遇到了这个问题。