Chris V.
Chris V.

Reputation: 1143

Losing partial view model form values

I have a form (using the primary viewmodel) and then a partial view to implement the address portion of the form (secondary viewmodel). When I submit the form, I'm not getting back the values of the inner, partial view part of the form. Not getting any errors, just losing the values of the partial. Code as follows:

"Main" portion of form:

@model REMS.ViewModels.AddComplexViewModel

@{
    ViewBag.Title = "Add Complex";
}

<h2>@ViewBag.Title</h2>

@{ Html.Partial("~/Views/Shared/Partials/ActionStatusPartial.cshtml", Model.ActionStatusMessageViewModel); }

@using (Html.BeginForm("AddComplex", "Admin", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Add a New Complex</h4>
    <hr />    
    <div class="form-group">
        @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
        </div>
    </div>

    @Html.Partial("~/Views/Shared/Partials/AddressFormPartial.cshtml", Model.AddressViewModel)

    <div class="form-group">
        @Html.Label("Owner", new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.DropDownList("SelectedOwner", Model.Owners, "Select an Owner...")
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Add" />
        </div>
    </div>
}

Partial view of form:

@model REMS.ViewModels.AddressViewModel

<div class="form-group">
@Html.LabelFor(m => m.Address1, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.TextBoxFor(m => m.Address1, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
    @Html.LabelFor(m => m.Address2, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.Address2, new { @class = "form-control" })
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(m => m.City, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.City, new { @class = "form-control" })
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(m => m.State, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.State, new { @class = "form-control" })
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(m => m.Zip, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.Zip, new { @class = "form-control" })
    </div>
</div>

View Models:

public class AddComplexViewModel
{
    [Display(Name = "Name")]
    public string Name { get; set; }

    [Display(Name = "AddressViewModel")]
    public AddressViewModel AddressViewModel { get; set; }

    [Display(Name = "SelectedOwner")]
    public Guid SelectedOwner { get; set; }

    [Display(Name = "Owners")]
    public SelectList Owners { get; set; }

    [Display(Name = "ActionStatusMessageViewModel")]
    public ActionStatusViewModel ActionStatusMessageViewModel { get; set; }

    public AddComplexViewModel()
    {
        ActionStatusMessageViewModel = new ActionStatusViewModel();
        AddressViewModel = new AddressViewModel();
    }
}


public class AddressViewModel
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

When I submit the form the address values are all null. Am I missing something?

Upvotes: 0

Views: 1785

Answers (2)

ragerory
ragerory

Reputation: 1376

Partial views are still technically views. You're unable to get the values from the partial just because it is inside of the main view's form.

Look into Editor Templates, they'll allow you to achieve what you're looking for.

More on that here

Upvotes: 0

Adrian Bystrek
Adrian Bystrek

Reputation: 608

Pass to partial view your main AddComplexViewModel model to generate right names for inputs. I assume that in AddComplex method you take AddComplexViewModel as parameter.

Change in main form:

@Html.Partial("~/Views/Shared/Partials/AddressFormPartial.cshtml", Model.AddressViewModel)

to:

@Html.Partial("~/Views/Shared/Partials/AddressFormPartial.cshtml", Model)

then in partial view change:

@model REMS.ViewModels.AddressViewModel

to:

@model REMS.ViewModels.AddComplexViewModel

and each lambda like:

m => m.Address1

to:

m => m.AddressViewModel.Address1

whole partial view after edit:

@model WebApplication2.Controllers.AddComplexViewModel

<div class="form-group">
@Html.LabelFor(m => m.AddressViewModel.Address1, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.TextBoxFor(m => m.AddressViewModel.Address1, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.AddressViewModel.Address2, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.TextBoxFor(m => m.AddressViewModel.Address2, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.AddressViewModel.City, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.TextBoxFor(m => m.AddressViewModel.City, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.AddressViewModel.State, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.TextBoxFor(m => m.AddressViewModel.State, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.AddressViewModel.Zip, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.TextBoxFor(m => m.AddressViewModel.Zip, new { @class = "form-control" })
</div>

Upvotes: 2

Related Questions