复杂视图模型中的多个表单 - 如何仅绑定其中之一?

sta*_*tch 5 asp.net-mvc

我有一个复杂的视图模型,其中包含使用编辑器和显示模板递归渲染的其他对象的集合。

集合中的每个项目都包含一个我想提交给控制器的表单模型。请注意,我不想再次发布整个视图模型,而只是表单模型。

我的问题是 MVC 将每个对象呈现为集合的一部分,并且我不知道如何将集合中的单个对象绑定到控制器签名中的对象。

我知道我可以使用 再次绑定全部内容IEnumerable<Account>,但我正在尝试创建行级提交而不是整个页面。

如果有人能给我指出正确的方向,或者告诉我如何在 MVC 世界中完成此操作(我来自 Web 表单,所以有点被宠坏了),我将非常感激。

我在下面提供了一个示例 HTML 片段以及我想要发布到的控制器。

<form action="/Home/Index" method="post">
    <input id="Accounts_0__AccountName" name="Accounts[0].AccountName" type="text" value="Account 1" />
    <input id="Accounts_0__AccountId" name="Accounts[0].AccountId" type="hidden" value="dddf5ca7-f8de-4192-b63a-3548f891e293" />
    <input type="submit" value="Submit" />    
</form>                  

<form action="/Home/Index" method="post">
    <input name="Accounts[1].AccountName" type="text" value="Account 2" />
    <input id="Accounts_1__AccountId" name="Accounts[1].AccountId" type="hidden" value="95d75f76-16ef-4cf2-b1e7-5fad782002c5" />
    <input type="submit" value="Submit" />    
</form>

[HttpPost]
public ActionResult Index(Account accounts)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

Dar*_*rov 4

您可以尝试在编辑器模板中设置前缀:

@model AppName.Models.Account
@{
    ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;
}
@using (Html.BeginForm("Index", "Home"))
{
    @Html.TextBoxFor(x => x.AccountName)
    @Html.HiddenFor(x => x.AccountId)
    <input type="submit" value="Submit" />  
}
Run Code Online (Sandbox Code Playgroud)

如果我没记错的话应该生成:

<form action="/Home/Index" method="post">
    <input id="AccountName" name="AccountName" type="text" value="Account 1" />
    <input id="AccountId" name="AccountId" type="hidden" value="dddf5ca7-f8de-4192-b63a-3548f891e293" />
    <input type="submit" value="Submit" />    
</form>
Run Code Online (Sandbox Code Playgroud)

显然,您意识到这样做最终会得到无效的 HTML(您将拥有多个具有相同 的元素id)。一个可能的解决方法是手动设置 id:

@Html.TextBoxFor(x => x.AccountName, new { id = "some unique value like a GUID" })
@Html.HiddenFor(x => x.AccountId, new { id = "some unique value like a GUID" })
Run Code Online (Sandbox Code Playgroud)

另一种可能性是为帐户类型编写自定义模型绑定器,该绑定器在绑定时会忽略前缀。