I have a model object structure with a Foo
class that contains a Bar
with a string value.
public class Foo
{
public Bar Bar;
}
public class Bar
{
public string Value { get; set; }
}
And a view model that uses that structure like this
public class HomeModel
{
public Foo Foo;
}
I then have a form in view that in Razor looks something like this.
<body>
<div>
@using (Html.BeginForm("Save", "Home", FormMethod.Post))
{
<fieldset>
@Html.TextBoxFor(m => m.Foo.Bar.Value)
<input type="submit" value="Send"/>
</fieldset>
}
</div>
</body>
In html that becomes.
<form action="/Home/Save" method="post">
<fieldset>
<input id="Foo_Bar_Value" name="Foo.Bar.Value" type="text" value="Test">
<input type="submit" value="Send">
</fieldset>
</form>
Finally the controller to handle the post loos like this
[HttpPost]
public ActionResult Save(Foo foo)
{
// Magic happends here
return RedirectToAction("Index");
}
My problem is that Bar
in Foo
is null
once it hits the Save
controller action (Foo
is created but with an null
Bar
field).
I thought the model binder in MVC would be able to create the Foo
and the Bar
object and set the Value
property as long as it looks like the above. What am I missing?
I also know my view model is a bit over complicated and could be simpler but I for what I'm trying to do I'd really help me if I could use the deeper object structure. The examples above uses ASP.NET 5.
I had the same problem, but once I created a HIDDEN FIELD for the foreign-key...it all worked just fine...
FORM EXAMPLE:
ACTION EXAMPLE:
PRETTY PICTURES:
I just discovered another reason this can happen, which is if your property is named
Settings
! Consider the following View model:In code, if you bind to the
Settings
property, it fails to bind (not just on post but even on generating the form). If you renameSettings
toDSettings
(etc) it suddenly works again.Firstly, the
DefaultModelBinder
will not bind to fields so you need to use propertiesSecondly, the helpers are generating controls based on
HomeModel
but you posting back toFoo
. Either change the POST method toor use the
BindAttribute
to specify thePrefix
(which essentially strips the value of prefix from the posted values - soFoo.Bar.Value
becomesBar.Value
for the purposes of binding)Note also that you should not name the method parameter with the same name as one of your properties otherwise binding will fail and your model will be null.
I had the same problem and after I followed @Stephen Muecke steps I realized that the problem was caused because my inputs were disabled (I was disabling them with JQuery on document ready) as you can see it here: How do I submit disabled input in ASP.NET MVC?. At the end I used read-only instead of disabled attribute and all the values were sent successfully to the controller.