default model binding does not work in case when m

2019-08-07 14:01发布

问题:

Here are my model.

public class InfoModel
    {
        public NameModel Name { get; set; }
        public string Phone { get; set; }
    }

public class NameModel
    {
        public string FirstName { get; set; }
        public string LastName  { get; set; }

        public NameModel(string first, string last)
        {
            this.FirstName = first;
            this.LastName = last;
        }
    }

Then I have a partial View just for displaying names as follows

@model MyTestApp.Models.NameModel

@Html.LabelFor( m => m.LastName) 
@Html.TextBoxFor( m => m.LastName)       
<br />
@Html.LabelFor( m => m.FirstName) 
@Html.TextBoxFor( m => m.FirstName)       

Then there is a view for ShowInfo

@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" />
}

Now user submit any info, following controller method is called

 [HttpPost]
 public ActionResult ShowInfo(InfoModel model)
 {
    ...
 }

Problem is when i inspect the value of model, phone is fine but name is null. Any ideas how to make it work?

回答1:

The DefaultModelBinder class uses Activator.CreateInstance(typeToCreate) internally to create the model classes. Your NameModel class dosn't have a default constructor so the DefaultModelBinder can't instantiate it. So if you add the default constructor it should work.

EDIT It won't work Partial view you need to use an EditorTemplate instead:
Create a folder under your view folder with the name EditorTemplates and put your ShowName.cshtml there add in your main view use:

@using(Html.BeginForm())
{
    @Html.EditorFor(m => m.Name, "ShowName")
    ...


回答2:

The DefaultModelBinder works if the Model class has a default constructor and the properties have get and set. In all other cases it doesn't work.

Example

public class Product
{
    public int id;
    public string name;
}

doesn't work.

public class Product
{
    public int id {get; set;}
    public string name {get; set;}

    public Product()
    {
    }
}

works.