Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

c# - Complex object and model binder ASP.NET MVC

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Firstly, the DefaultModelBinder will not bind to fields so you need to use properties

public class HomeModel
{
  public Foo Foo { get; set; }
}

Secondly, the helpers are generating controls based on HomeModel but you posting back to Foo. Either change the POST method to

[HttpPost]
public ActionResult Save(HomeModel model)

or use the BindAttribute to specify the Prefix (which essentially strips the value of prefix from the posted values - so Foo.Bar.Value becomes Bar.Value for the purposes of binding)

[HttpPost]
public ActionResult Save([Bind(Prefix="Foo")]Foo model)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...