asp.net 绑定对象数组而不指定数组索引

v6ylcynt  于 2023-11-20  发布在  .NET
关注(0)|答案(2)|浏览(102)

我有一个剃刀页,并希望提交一个对象数组,并自动绑定它们。
但是,这些对象将在客户端进行编辑(添加、编辑和删除)。因此,与其指定每个数组项的索引(name=Ship.Products[1].ProductId),不如省略索引(name=Ship.Products[].ProductId)。
但是,Razor Pages似乎无法识别没有数组索引的数据。

型号

public class EditShipViewModel
{
    public int Id { get; set; }

    [Required]
    [StringLength(80)]
    public string Name { get; set; }

    [StringLength(80)]
    public string Shipper { get; set; }

    [StringLength(80)]
    [DisplayName("Port of Origin")]
    public string PortOfOrigin { get; set; }

    [DisplayName("Is Empty")]
    public bool IsEmpty { get; set; }

    [DisplayName("ETA")]
    public DateTime? Eta { get; set; }
    public DateTime? Arrival { get; set; }
    public DateTime? Departure { get; set; }

    public IEnumerable<EditShipProductViewModel> Products { get; set; }
}

public class EditShipProductViewModel
{
    public int Id { get; set; }
    [DisplayName("Product")]
    public int ProductId { get; set; }
    [DisplayName("Inbound Quantity")]
    public double InboundQuantity { get; set; }
}

字符串

属性

[BindProperty]
public EditShipViewModel Ship { get; set; }

标记

<table class="table table-striped">
    <tbody id="ship-products">
        <tr>
            <td>
                <input name="Ship.Products[].Id" type="hidden" value="1">
                <input name="Ship.Products[].ProductId" type="hidden" value="1">
            </td>
            <td>
                <input name="Ship.Products[].InboundQuantity" type="hidden" value="1000">
            </td>
            <td class="text-end">[Edit][Delete]</td>
        </tr>
        <tr>
            <td>
                <input name="Ship.Products[].Id" type="hidden" value="2">
                <input name="Ship.Products[].ProductId" type="hidden" value="2">
            </td>
            <td>
                <input name="Ship.Products[].InboundQuantity" type="hidden" value="2000">
            </td>
            <td class="text-end">[Edit][Delete]</td>
        </tr>
        <tr>
            <td>
                <input name="Ship.Products[].Id" type="hidden" value="3">
                <input name="Ship.Products[].ProductId" type="hidden" value="3">
            </td>
            <td>
                <input name="Ship.Products[].InboundQuantity" type="hidden" value="3000">
            </td>
            <td class="text-end">[Edit][Delete]</td>
        </tr>
    </body>
</table>


有没有办法让Razor Pages绑定将这个标记识别为一个对象数组?

更新

这是发布到我的页面的实际数据。


的数据

neekobn8

neekobn81#

但是,这些对象将在客户端进行编辑(添加、编辑和删除
如果要避免由于数组项的索引未从零开始按顺序编号而导致模型绑定失败,
您可以尝试替换数组的索引,并添加一个名为Ship.Products.index的输入,如下所示。这被称为 * 显式 * 索引:

<tr>
                <td>
                    <input name="Ship.Products[a].Id" type="hidden" value="1">
                    <input name="Ship.Products[a].ProductId" type="hidden" value="1">
                    <input name="Ship.Products.index" type="hidden" value="a">
                </td>
                <td>
                    <input name="Ship.Products[a].InboundQuantity" type="hidden" value="1000">
                </td>
                <td class="text-end">[Edit][Delete]</td>
            </tr>
 <tr>
                <td>
                    <input name="Ship.Products[b].Id" type="hidden" value="1">
                    <input name="Ship.Products[b].ProductId" type="hidden" value="1">
                    <input name="Ship.Products.index" type="hidden" value="b">
                </td>
                <td>
                    <input name="Ship.Products[b].InboundQuantity" type="hidden" value="1000">
                </td>
                <td class="text-end">[Edit][Delete]</td>
            </tr>

字符串

kmpatx3s

kmpatx3s2#

简短的回答:不。
你可以绑定一个简单值的集合,比如name=1&name=2&name=3int[] name。但是这不可能适用于复杂的对象,因为服务器没有逻辑方法来判断一个项目何时停止,另一个项目何时开始。
如果你不想担心提交连续值,那么你可以绑定一个Dictionary<int,T>而不是一个List<T>。这样客户端可以生成新的字典键,但也可以删除它们,而不需要重新编号其他所有东西。

public IDictionary<int, EditShipProductViewModel> Products { get; set; }

个字符
作为一个副作用,这种方法可以很好地在重新呈现相同的模板时在ModelState中保留用户提供的值,即使用户提供的数据无法解析。

相关问题