1

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

Community
  • 1
  • 1
palm snow
  • 2,392
  • 4
  • 29
  • 49

1 Answers1

2

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.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • As stated in my question, problem with using editor template is it does not display the List Titles as drop-down. What am I suppose to do with that? – palm snow Dec 22 '11 at 14:56
  • @palmsnow, why it is not displaying properly? What does it display instead? Also you seem to be using some wrong overload. You should use `@Html.DropDownListFor(m => m.Title, Model.Titles)`. This should work fine. – Darin Dimitrov Dec 22 '11 at 15:00
  • I tried with other overload also. The drop-down is displayed as a Edit box. May be because its a collection or something? – palm snow Dec 22 '11 at 15:03
  • 1
    @palmsnow, that's very weird, `DropDownListFor` should always generate a ` – Darin Dimitrov Dec 22 '11 at 15:03
  • You are the man. Actually my path was incorrect. After fixing it, code worked like a charm – palm snow Dec 22 '11 at 15:08