Complex object and model binder ASP.NET MVC

34,573

I just discovered another reason this can happen, which is if your property is named Settings! Consider the following View model:

public class SomeVM
{
    public SomeSettings DSettings { get; set; } // named this way it will work

    public SomeSettings Settings { get; set; } // property named 'Settings' won't bind!

    public bool ResetToDefault { get; set; }
}

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 rename Settings to DSettings (etc) it suddenly works again.

Share:
34,573
Riri
Author by

Riri

Fantomen

Updated on September 27, 2020

Comments

  • Riri
    Riri over 3 years

    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.