ASP.NET 未知长度的核心模型绑定集合
ASP.NET Core Model Bind Collection of Unknown Length
我正在尝试研究如何将集合建模绑定到 asp.net 核心中的模型 属性。我知道这样做的方法是这样包含字段:
<input type="hidden" asp-for="items[0].Id" />
<input type="hidden" asp-for="items[0].Name" />
<input type="hidden" asp-for="items[1].Id" />
<input type="hidden" asp-for="items[1].Name" />
但是,如果您想让用户添加其他项目,您会怎么做 and/or 删除其他项目。在这种情况下,我在客户端使用 javascript 添加这些项目,他们可能会在末尾添加一个新项目并从中间删除一个项目,这可能会导致类似以下内容:
<input type="hidden" asp-for="items[1].Id" />
<input type="hidden" asp-for="items[1].Name" />
<input type="hidden" asp-for="items[3].Id" />
<input type="hidden" asp-for="items[3].Name" />
ASP.NET 核心模型绑定不会将集合绑定到模型 属性(我推测是因为索引未对齐)。
有什么方法可以让它工作吗?我试图避免必须向 "relabel" 这些字段的索引写入内容。
更新
对于遇到此问题的任何其他人,我将所有元素添加到名称为 0 的容器内的页面,如下所示:
<div class="some-group">
<input type="hidden" class="id" asp-for="items[0].Id" />
<input type="hidden" class="name" asp-for="items[0].Name" />
<input type="hidden" class="id" asp-for="items[0].Id" />
<input type="hidden" class="name" asp-for="items[0].Name" />
</div>
然后我添加了以下循环并在提交表单时重命名它们。
$('#frmSomething').submit(function (e) {
var selectors = $('.some-group');
var id = 0;
selectors.each(function (i, el) {
var idItem = $(el).find('input.id');
idItem.prop('name', idItem.prop('name').replace('0', id));
var nameItem = $(el).find('input.name');
nameItem.prop('name', nameItem.prop('name').replace('0', id));
id++;
});
});
仅在提交表单后才对项目进行顺序编号,这意味着用户可以添加和删除他们喜欢的项目的任意组合,而不会影响向控制器提交值。
我相信有人可以想出更好的方法来解决这个问题(我不是 javascript 专家)但这对我有用并且可能会帮助其他人。
更新 2
下面@LukasKubris 提供的答案是正确的,它比编写映射函数更容易。
您还可以绑定Non-Sequential个索引。它只需要名为 Index 的额外字段。所以不需要一些辅助JS函数。
<form method="POST">
<input type="hidden" name="items.Index" value="7466c69d-4575-4636-9151-f92edd9c25b7" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b7].Key" value="key1" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b7].Value" value="value1" />
<input type="hidden" name="items.Index" value="7466c69d-4575-4636-9151-f92edd9c25b8" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b8].Key" value="key2" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b8].Value" value="value2" />
<input type="submit"/>
</form>
在 OnPost 处理程序中的用法
public void OnPost(List<Item> items)
{
}
我正在尝试研究如何将集合建模绑定到 asp.net 核心中的模型 属性。我知道这样做的方法是这样包含字段:
<input type="hidden" asp-for="items[0].Id" />
<input type="hidden" asp-for="items[0].Name" />
<input type="hidden" asp-for="items[1].Id" />
<input type="hidden" asp-for="items[1].Name" />
但是,如果您想让用户添加其他项目,您会怎么做 and/or 删除其他项目。在这种情况下,我在客户端使用 javascript 添加这些项目,他们可能会在末尾添加一个新项目并从中间删除一个项目,这可能会导致类似以下内容:
<input type="hidden" asp-for="items[1].Id" />
<input type="hidden" asp-for="items[1].Name" />
<input type="hidden" asp-for="items[3].Id" />
<input type="hidden" asp-for="items[3].Name" />
ASP.NET 核心模型绑定不会将集合绑定到模型 属性(我推测是因为索引未对齐)。
有什么方法可以让它工作吗?我试图避免必须向 "relabel" 这些字段的索引写入内容。
更新
对于遇到此问题的任何其他人,我将所有元素添加到名称为 0 的容器内的页面,如下所示:
<div class="some-group">
<input type="hidden" class="id" asp-for="items[0].Id" />
<input type="hidden" class="name" asp-for="items[0].Name" />
<input type="hidden" class="id" asp-for="items[0].Id" />
<input type="hidden" class="name" asp-for="items[0].Name" />
</div>
然后我添加了以下循环并在提交表单时重命名它们。
$('#frmSomething').submit(function (e) {
var selectors = $('.some-group');
var id = 0;
selectors.each(function (i, el) {
var idItem = $(el).find('input.id');
idItem.prop('name', idItem.prop('name').replace('0', id));
var nameItem = $(el).find('input.name');
nameItem.prop('name', nameItem.prop('name').replace('0', id));
id++;
});
});
仅在提交表单后才对项目进行顺序编号,这意味着用户可以添加和删除他们喜欢的项目的任意组合,而不会影响向控制器提交值。
我相信有人可以想出更好的方法来解决这个问题(我不是 javascript 专家)但这对我有用并且可能会帮助其他人。
更新 2
下面@LukasKubris 提供的答案是正确的,它比编写映射函数更容易。
您还可以绑定Non-Sequential个索引。它只需要名为 Index 的额外字段。所以不需要一些辅助JS函数。
<form method="POST">
<input type="hidden" name="items.Index" value="7466c69d-4575-4636-9151-f92edd9c25b7" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b7].Key" value="key1" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b7].Value" value="value1" />
<input type="hidden" name="items.Index" value="7466c69d-4575-4636-9151-f92edd9c25b8" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b8].Key" value="key2" />
<input type="text" name="items[7466c69d-4575-4636-9151-f92edd9c25b8].Value" value="value2" />
<input type="submit"/>
</form>
在 OnPost 处理程序中的用法
public void OnPost(List<Item> items)
{
}