ASP.NET MVC 在一个视图中创建具有相关对象的对象

ASP.NET MVC Creating an object with related object in one view

我是 ASP.NET MVC 的新手,我想创建一个视图,我可以在其中创建新对象以及相关对象。

例如:我有以下 class 人:

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual List<Address> Addresses { get; set; }
}

以及 class 地址:

public class Address
{
    public int AddressId { get; set; }
    public string City { get; set; }
    public string Street { get; set; }

    public int PersonId { get; set; }
    public virtual Person Person { get; set; }
}

我想要实现的是拥有一个视图,用户可以在其中输入此人的数据以及此用户的任意数量的地址。

我的第一次(简单)尝试只是提供一个映射到控制器方法的操作 link。此方法将一个 Person 对象作为参数,将一个 Address 对象添加到集合 Addresses 和 returns 一个新的创建视图(可能不太好,但它有效)。但是当我尝试添加第二个地址时,我注意到这个人的地址集合又是空的。

有sugesstions/best这种问题的做法吗?

谢谢!

我建议您采用以下方法:

1.Create 一个视图模型:

public class AddressViewModel
{ 
    public string City { get; set; }
    public string Street { get; set; }
}

public class PersonViewModel()
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public AddressViewModel AddressViewModelTemplate {get; set;}
    public Collection<AddressViewModel> Addresses {get; set;}
}

然后在您的视图中,您可以为 AddressViewModelTemplate 使用隐藏的 EditorTempalete,并在单击某些按钮时用 javascript 显示它。当然,您必须为绑定调整生成的集合的名称。

示例编辑器模板。您可以选择更好的结构。

    @model AddressViewModel
    <div>
        <div>@Html.LabelFor(x => x.City)</div>
        <div>@Html.TextBoxFor(x => x.City)</div>
    </div>
    <div>
        <div>@Html.LabelFor(x => x.Street)</div>
        <div>@Html.TextBoxFor(x => x.Street)</div>
    </div>

在您的强类型视图中:

@model PersonViewModel;
@using(Html.BeginForm())
{
    //Display textbox for Person properties here
    ....
    <div id="addressInfo" style:"dislpay:none">
        @Html.EditorFor(x => x.AddressViewModelTemplate)
    </div>
    ....
    <div id="AddressesWraper">
        <input id="btnAddAddress" type="button" value="Add new Address" />
    <div>
}
<script>
    $(document).ready(function(){
        $("#btnAddAddress").click(function(){
            $("#AddressesWraper").append("#addressInfo").html();
            refreshAddressNames();
        });
    });
    function refreshAddressNames(){
        /*Here you should name your addresses like this:
          name="AddressViewModel.Addresses[0].City"
          name="AddressViewModel.Addresses[0].Street"
          name="AddressViewModel.Addresses[1].City"
          name="AddressViewModel.Addresses[1].Street"
          ................................[2].City"
                                          [2].Street"

        If you want delete option, you have to mind that too and reorder the collection propely*/
    }
</script>