简体   繁体   中英

MVC model binding to nested classes

When I try and create a new 'Flow' class the nested classes ('Action') always come back as null in the controller

So I have classes within classes like so:

public class Flow
{
    private Action actionField
    private string nameField
    private bool enabledField
    ...
}

public class Action
{
    private ActionSchedule actionScheduleField
    private ActionParameter actionParameterField
    private nameField
}
public class ActionSchedule
...

And a single create view for a 'Flow'

@model ProjectZeus.Models.Flow
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

   @Html.TextBoxFor(model => model.name, new { @placeholder = "Flow name" })
   @Html.ValidationMessageFor(model => model.name)


   @Html.LabelFor(model => model.enabled)

   @Html.EditorFor(model => model.enabled)
   @Html.ValidationMessageFor(model => model.enabled)

@Html.Partial("FlowAction")
...

and then partial views for each of the subclasses

@model ProjectZeus.Models.FlowAction

    @Html.TextBoxFor(model => model.name, new { @placeholder = "Action name" })
    ...

I've tried creating instances of the classes and calling the view - error,

I've tried creating instances of the classes in the views themselves - error,

I've tried not using PartialViews:

@Html.TextBoxFor(model => model.action.name, new { @placeholder = "Action name" })

I've googled and googled and googleedddd but with no luck, help please!?

Edit:

Implementing a customer model binder seems like overkill. This page describes the same problem but the solution code won't compile for me 'The name 'helper' does not exist in the current context'? - http://danielhalldev.wordpress.com/2013/08/23/partial-views-and-nested-mvc-model-binding/

Edit2:

I changed the model defintions for brevity - the model is actually auto generated from an xsd:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class D53ESBFlow
{

    private D53ESBFlowAction actionField;

    [Required]
    private string nameField;

    ...

    private bool enabledField;

    /// <remarks/>
    public D53ESBFlowAction action
    {
        get
        {
            return this.actionField;
        }
        set
        {
            this.actionField = value;
        }
    }
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;

Edit 3 (bump):

It looks like the 'binder'is creating a property and not a class object? 你在哪

Did you forget the { get; set; } accessors on the property names?

I had a similar issue with MVC 5, .NET 4.5, Visual Studio 2013.

Here's what worked for me: Add a constructor so the contained class gets instantiated, make them properties (not variables) like AntoineLev said, and add the class to the Binding:

public class Flow
{
    public Action actionField {get; set; }

    public class Flow()
    {
        actionField = new Action();  // otherwise it shows up as null
    }
}

In your controller, Add the the whole class in the binding:

public ActionResult Create([Bind(Include="action,name,enabled")] Flow flow)
{
   ... 
}

Your Mileage may vary.

}

I ended up going through the request response and mapping all the properties individually by name:

flow.action = new D53ESBFlowAction
    {
        name = Request["action.name"],
        ...

I had similar troubles and this article of Jimmy's Bogard helped me. Article here

Look at the html generated will show that with a partial view the html doesn't include the name of the nested class so by default is unable to bind it. Giving the binding statement as in one of the answers above solves the problem

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM