Reputation: 2392
Its similar question that I asked yesterday here with a slight modification.
Here are my models
public class InfoModel
{
public NameModel Name { get; set; }
public string Phone { get; set; }
}
public class NameModel
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<SelectListItem> Titles
{
get
{
var list = new List<SelectListItem>();
list.Add(new SelectListItem() { Text = "Mr.", Value = "Mr." });
list.Add(new SelectListItem() { Text = "Mrs.", Value = "Mrs." });
list.Add(new SelectListItem() { Text = "Ms.", Value = "Ms." });
return list;
}
}
public NameModel()
{
}
public NameModel(string first, string last)
{
this.FirstName = first;
this.LastName = last;
}
}
Then I have my first view ShowName.cshtml as follows
@model MyTestApp.Models.NameModel
@Html.DropDownListFor(m => m.Title, Model.Titles, Model.Titles)
<br />
@Html.LabelFor( m => m.LastName)
@Html.TextBoxFor( m => m.LastName)
<br />
@Html.LabelFor( m => m.FirstName)
@Html.TextBoxFor( m => m.FirstName)
the above view is used in ShowInfo.cshtml as below
@model MyTestApp.Models.InfoModel
@using (Html.BeginForm())
{
@Html.Partial("ShowName", Model.Name)
<br />
@Html.LabelFor(m => m.Phone)
@Html.TextBoxFor(m => m.Phone)
<br />
<input type="submit" value="Submit Info" />
}
When User submit any info, follwoing controller method is called
[HttpPost]
public ActionResult ShowInfo(InfoModel model)
{
...
}
The problem is that phone is fine but name is null. If I change my call of @Html.Partial("ShowName", Model.Name)
to @Html.EditorFor(m => m.Name, "ShowName")
then the drop-down for Titles is displayed as an Editbox
Upvotes: 1
Views: 249
Reputation: 1038710
I would recommend you using editor templates. So instead of the Html.Partial
use:
@Html.EditorFor(x => x.Name, "ShowName")
and then move the partial to ~/Views/Shared/EditorTemplates/ShowName.cshtml
.
Here's the reason why the partial doesn't work: it generates wrong names for the input fields. So when you write:
@Html.TextBoxFor(m => m.LastName)
this generates the following markup:
<input type="text" name="LastName" id="LastName" value="" />
whereas you need:
<input type="text" name="Name.LastName" id="Name_LastName" value="" />
for the default model binder to work correctly and assign the LastName property of the Name property on your main view model.
When you use editor templates, as shown in my example, they automatically take care of the association paths and generate proper names for the input elements.
Upvotes: 2