Looks like others have had this problem but I can't seem to find a solution.
I have 2 Models: Person & BillingInfo:
public class Person
{
public string Name { get; set;}
public BillingInfo BillingInfo { get; set; }
}
public class BillingInfo
{
public string BillingName { get; set; }
}
And I'm trying to bind this straight into my Action using the DefaultModelBinder.
public ActionResult DoStuff(Person model)
{
// do stuff
}
However, while the Person.Name property is set, the BillingInfo is always null.
My post looks like this:
"Name=statichippo&BillingInfo.BillingName=statichippo"
Why is BillingInfo always null?
Status no repro. Your problem is elsewhere and unable to determine where from what you've given as information. The default model binder works perfectly fine with nested classes. I've used it an infinity of times and it has always worked.
Model:
public class Person
{
public string Name { get; set; }
public BillingInfo BillingInfo { get; set; }
}
public class BillingInfo
{
public string BillingName { get; set; }
}
Controller:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new Person
{
Name = "statichippo",
BillingInfo = new BillingInfo
{
BillingName = "statichippo"
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(Person model)
{
return View(model);
}
}
View:
<% using (Html.BeginForm()) { %>
Name: <%: Html.EditorFor(x => x.Name) %>
<br/>
BillingName: <%: Html.EditorFor(x => x.BillingInfo.BillingName) %>
<input type="submit" value="OK" />
<% } %>
Posted values: Name=statichippo&BillingInfo.BillingName=statichippo
is perfectly bound in the POST action. Same works with GET as well.
One possible case when this might not work is the following:
public ActionResult Index(Person billingInfo)
{
return View();
}
Notice how the action parameter is called billingInfo
, same name as the BillingInfo
property. Make sure this is not your case.
I had this problem, and the answer was staring me in the face for a few hours. I'm including it here because I was searching for nested models not binding and came to this answer.
Make sure that your nested model's properties, like any of your models that you want the binding to work for, have the correct accessors.
// Will not bind!
public string Address1;
public string Address2;
public string Address3;
public string Address4;
public string Address5;
// Will bind
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string Address4 { get; set; }
public string Address5 { get; set; }
This is what worked for me.
I changed this:
[HttpPost]
public ActionResult Index(Person model)
{
return View(model);
}
To:
[HttpPost]
public ActionResult Index(FormCollection fc)
{
Person model = new Person();
model.BillingInfo.BillingName = fc["BillingInfo.BillingName"]
/// Add more lines to complete all properties of model as necessary.
return View(model);
}
public class MyNestedClass
{
public string Email { get; set; }
}
public class LoginModel
{
//If you name the property as 'xmodel'(other than 'model' then it is working ok.
public MyNestedClass xmodel {get; set;}
//If you name the property as 'model', then is not working
public MyNestedClass model {get; set;}
public string Test { get; set; }
}
I have had the similiar problem. I spent many hours and find the problem accidentally that I should not use 'model' for the property name
@Html.TextBoxFor(m => m.xmodel.Email) //This is OK
@Html.TextBoxFor(m => m.model.Email) //This is not OK
I had the same issue, the previous developer on the project had the property registered with a private setter as he wasn't using this viewmodel in a postback. Something like this:
public MyViewModel NestedModel { get; private set; }
changed to this:
public MyViewModel NestedModel { get; set; }