ASP.NET Core Model Bind Collection of Unknown Length

六眼飞鱼酱① 提交于 2020-01-04 05:48:06

问题


I'm trying to work out how to model bind a collection to a model property within asp.net core. I understand that the way this can be done is to include fields as so:

<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" />

However what do you do if you want to allow the user to add additional items and/or remove others. In this case I am adding these items client side using javascript and they might add a new item to the end and delete one from the middle, which could result in something like the following:

<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 Cores model binding doesn't then bind the collection to the model property (I presume because the indexes aren't aligned).

Is there any way to make this work? I'm trying to avoid having to write something to "relabel" the indexes of these fields.

UPDATE

For anyone else stumbling across this I add all of the elements to the page inside a container with the name of 0 like this:

<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>

I then added the following to loop and rename them when the form was submitted.

$('#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++;
    });
});

This sequentially numbers the items only once a form is submitted meaning users can add and remove any combination of items they like without effecting the submission of values to the controller.

I'm sure someone could come up with a better way of solving this (I'm no javascript expert) but this works for me and might help someone else.

UPDATE 2

Answer provided below from @LukasKubris is correct, it's easier than writing a mapping function.


回答1:


You can also bind Non-Sequential Indices. It just requires extra field called Index. So there is no need to have some helper JS functions.

<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>

usage in OnPost handler

public void OnPost(List<Item> items)
{
}


来源:https://stackoverflow.com/questions/49051665/asp-net-core-model-bind-collection-of-unknown-length

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!