ASP.NET MVC 视图模型绑定:如何填充对象集合



直到几天前,在我的应用程序中管理模型绑定还非常容易。我有一个视图模型,叫做 PersonOfferDTO ,包含一组PersonProductOfferDTO。(是的,我使用 DTO 作为视图模型,因为在这种情况下,视图模型等于 DTO(。下面是PersonOfferDTO的简化版本

public class PersonOfferDTO
{
    [DataMember]
    public Guid PersonOfferId { get; private set; }
    [DataMember]
    public ICollection<PersonProductOfferDTO> Offers { get; set; }
}

下面是PersonProductOfferDTO的简化版本

public class PersonProductOfferDTO
{
    [DataMember]
    public Guid PersonProductOfferId { get; private set; }
    [DataMember]
    public Guid PersonOfferId { get; set; }
    [DataMember]
    public int Quantity { get; set; }
    [DataMember]
    public decimal UnitPrice { get; set; }
}

由于下面显示的方法(HTML 代码(,我能够填充ICollection

<form method="POST" action="/Offers/AddNewPersonOffer">
    <input name="PersonProductOffers.Index" value="myKey1" hidden>
    <input name="PersonProductOffers[myKey1].Quantity">
    <input name="PersonProductOffers[myKey1].UnitPrice">
    <input name="PersonProductOffers.Index" value="myKey2" hidden>
    <input name="PersonProductOffers[myKey2].Quantity">
    <input name="PersonProductOffers[myKey2].UnitPrice">
</form>

但是在最后几天,我增加了对象树的深度,所以现在我有以下代码。

public class PersonOfferDTO
{
    [DataMember]
    public Guid PersonOfferId { get; private set; }
    [DataMember]
    public ICollection<PersonOfferParagraphDTO> Paragraphs { get; set; }
}
[DataContract]
public class PersonOfferParagraphDTO
{
    [DataMember]
    public Guid PersonOfferParagraphId { get; set; }
    [DataMember]
    public ICollection<PersonProductOfferDTO> PersonProductOffers { get; set; }
}

如您所见,现在在 PersonOfferDTOPersonProductOfferDTO 之间还有一个级别,我不知道如何执行"多级绑定":创建一个具有更多PersonOfferParagraphDTO每个PersonOfferDTO包含更多PersonProductOfferDTO

注意:我不想使用增量索引 ([0] , [1], ....(...而是一个字符串(["我的密钥"](

编辑

根据要求,我在下面添加控制器

public ActionResult AddNewPersonOffer(PersonOfferDTO offer)
{
    if (!UserHasPermissions())
    {
        return PartialView("_forbidden");
    }
    var errors = OffersCRUD.AddNewPersonOffer(offer);
    if(errors.Count() == 0)
    {
        return RedirectToAction("Index");
    }
    return PartialView("_errors", new ErrorsViewModel(errors));
}

如果要使用自己的键填充它们,则可以在视图模型中将集合定义为接受非整数索引值Dictionary<string, YOURCLASS>

使用字典的示例视图模型:

public class ViewModelTest
{
   public Dictionary<string, Class1> Values { get; set; }
}

要在字典集合中使用的示例类:

public class Class1
{
    public int MyProperty { get; set; }
    public Dictionary <string, Class2> MoreValues { get; set; }
}
public class Class2
{
    public int AnotherProperty { get; set; }
}

下面是填充值的表单:

@using (Html.BeginForm())
{
    <input type="text" name="Values[yourkey1].MyProperty" />
    <input type="text" name="Values[yourkey1].MoreValues[anotherKey1].AnotherProperty" />
    <input type="text" name="Values[yourkey2].MyProperty" />
    <input type="text" name="Values[yourkey2].MoreValues[anotherKey2].AnotherProperty" />
    <input type="submit" />
}

您可以使用帮助程序方法并享受智能感知,而不是自己编写 input 标记,假设您在视图中定义了视图模型,并且具有在操作方法中定义的相同结构:

@model ViewModelTest
@using (Html.BeginForm())
{ 
    @Html.TextBoxFor(x => x.Values[yourkey1].MyProperty)
    @Html.TextBoxFor(x => x.Values[yourkey1].MoreValues[anotherKey1].AnotherProperty)
    @Html.TextBoxFor(x => x.Values[yourkey2].MyProperty)
    @Html.TextBoxFor(x => x.Values[yourkey2].MoreValues[anotherKey2].AnotherProperty)
    <input type="submit" />
}

当然,您必须为此引入一个视图模型,而不仅仅是使用DTO;)。

PS:DTO也不应该用作域模型,它用于在图层周围传输信息。

最新更新