ASP.Net MVC3模型绑定IEnumerable <t>与编辑模板</t>

时间:2011-10-20 05:31:52

标签: c# asp.net-mvc-3 binding model controller

全部,请清除我对模型绑定如何与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!
}

3 个答案:

答案 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,因此您遇到了这个问题。