To illustrate the problem I face, I have put together three simple data models:
public class PersonalModel {
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class AddressModel {
public string Street { get; set; }
}
public class OverallModel {
public string Id { get; set; }
public PersonalModel Personal { get; set; }
public AddressModel Address { get; set; }
}
Here is my simple Index.chtml:
@model WebAppTest.Models.OverallModel
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>OverallModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div>
@Html.Partial("Personal", Model.Personal)
</div>
<div>
@Html.Partial("Address", Model.Address)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
When the "Save" button is clicked, the following controller method gets invoked:
[HttpPost]
public ActionResult Index(OverallModel model) {
return View(model);
}
The problem I have is that model.Personal
and model.Address
values always show up as null in the controller method.
Although the values are correctly getting passed to the partial views, the Razor engine is not able to put the overall object back together when submit is clicked.
Would appreciate it if you could enlighten me on what is it that I am missing. Regards.
I had same problem like you, so I'll put my 2 cents here for someone in the future with same problem.
My solution is by using EditorTemplates.
You create you models aka Personal, Address, Overal.
In (put whatever name)Controller you make an instance of Overal model and into Get method you send it into your View and in Post method you put it as incoming parameter.
Index page (i will use yours) will look like this
Istead of PartialViews we can use EditorModels, i understand it as a PartialView which we can use as editor whenever we want.
So to use it, we create folder called EditorTemplates in the Views/Shared and create Views with same names as your models.
For example EditorTemplate for our PersonalModel will be called PersonalModel.cshtml and code in it can look something like this
So when we write in our sou
@Html.EditorFor(m => m.Personal)
it will look into EditorTemplates and will search for an EditorTemplate with same name and use it in site.Index site will look like this
and when you click Submit button it will send back whole model back into Controller
Looks like it worked and we got our data back from view and use it for whatever we want to.
PS: My first post, so i hope it is understandable and will be helpful for others even now and in future. Have a good day
Pass the
OverallModel
to your partials so that the controls will be correctly named for posting back toOverallModel
. Currently you would have controls withname="FirstName"
but they need to bename="Personal.FirstName"
and change the partials to suit
As an alternative, you can also pass the prefix to the partial