Editing and saving complex objects

廉价感情. 提交于 2019-12-03 13:13:24

I guess ModelState.IsValid is false because you didn't populate the shipping addresses collection properly. This happened because you didn't use proper names for your input fields. Take a look at the following article to understand better what format does the model binder expects your input fields to be named in order to be able to reconstruct values back.

The reason your code is not generating correct input names is because you used this foreach loop in which the view lost track of the navigation context.

So try like this:

@for (var i = 0; i < Model.ShippingAddresses.Count; i++)
{
    <div>
        @Html.LabelFor(x => x.ShippingAddresses[i].Line1): 
        @Html.EditorFor(x => x.ShippingAddresses[i].Line1)

        @Html.LabelFor(x => x.ShippingAddresses[i].Line2): 
        @Html.EditorFor(x => x.ShippingAddresses[i].Line2)

        @Html.LabelFor(x => x.ShippingAddresses[i].City): 
        @Html.EditorFor(x => x.ShippingAddresses[i].City)

        @Html.LabelFor(x => x.ShippingAddresses[i].State): 
        @Html.EditorFor(x => x.ShippingAddresses[i].State)

        @Html.LabelFor(x => x.ShippingAddresses[i].ZipCode): 
        @Html.EditorFor(x => x.ShippingAddresses[i].ZipCode)
    </div>    
}

Remark: notice that I have also replaced your duplicate labels with an EditorFor call to effectively generate input fields for those fields.

or even better using editor templates like this:

@model Contact

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.FirstName): 
    @Html.EditorFor(x => x.FirstName)

    @Html.LabelFor(x => x.LastName): 
    @Html.EditorFor(x => x.LastName)

    @Html.LabelFor(x => x.Telephone): 
    @Html.EditorFor(x => x.Telephone)

    @Html.EditorFor(x => x.BillingAddress)

    @Html.EditorFor(x => x.ShippingAddresses)
}

and then define a custom editor template which will automatically be rendered for each element of the ShippingAddresses collection (~/Views/Shared/EditorTemplates/Address.cshtml):

@model Address
<div>
    @Html.LabelFor(x => x.Line1): 
    @Html.EditorFor(x => x.Line1)

    @Html.LabelFor(x => x.Line2): 
    @Html.EditorFor(x => x.Line2)

    @Html.LabelFor(x => x.City): 
    @Html.EditorFor(x => x.City)

    @Html.LabelFor(x => x.State): 
    @Html.EditorFor(x => x.State)

    @Html.LabelFor(x => x.ZipCode): 
    @Html.EditorFor(x => x.ZipCode)
</div>

Now you should no longer worry about getting wrong input names. And not only this but you are reusing the address editor template for both your billing address and the collection of shipping addresses. It makes your views DRYier.

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