0

I'm doing an ASP.NET MVC project, I have a nested model as below:

public class A
.........

public class B
.............

public class AB
{
  public A _a;
  public B _b;
  public AB()
  {
    _a = new A();
    _b = new B();
  }
}

and in controller:

public ActionResult Create()
{
  AB model = new AB();
  return View(model);
}

[HttpPost]
public ActionResult Create(AB abModel)
{
  //all properties of abModel._a and abModel._b are null 
  return View(abModel);
}

My view is a strongly typed view of AB model class, I don't know why all the values post back are null, this happens only for nested models . Am I missing something ?

Thanks for helping me

Updated model as @rene proposed

public class AB
{
  public A _a {get; set};
  public B _b {get; set};
  public AB()
  {
    _a = new A();
    _b = new B();
  }
}

View code:

  @model TestMVC.AB    
    @{
        ViewBag.Title = "Create";
    }
    @using (Html.BeginForm()) {
     @Html.ValidationSummary(true)
       <table cellspacing="0" cellpadding="0" class="forms">

       <tbody>
              <tr><th>
            @Html.LabelFor(model => model._a.ClientName)
      </th>
      <td>
            @Html.TextBoxFor(model => model._a.ClientName, new { @class = "inputbox"})
            @Html.ValidationMessageFor(model => model._a.ClientName)
       </td></tr>
      <tr><th></th><td><input type="submit" value="Create" /></td></tr>
      </tbody></table>

    }
0

2 Answers 2

2

MVC Model binder only binds to Properties not to fields. This model works for me in MVC3 with your Controller and View

Change your model classes as follows:

public class A
{
    public string ClientName { get; set; }
}

public class B
{
    public string Address { get; set; }
}

public class AB
{
    public A  _a { get; set;}
    public B _b { get; set;  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

did you also change your view to match with the model I proposed?
I didn't change the view as the way to access its properties is the same. Please look at my updated model code as you proposed. Thanks for helping me :)
does class A now has a property ClientName or a field?
Even though you initialize _a and _b, the model binder will try to create new objects and set them. Is there anything that would prevent the binder from doing so? Such as the constructors being marked internal? (I don't know offhand if there would be an exception generated from that.)
This is extremely useful, i was about to screw everything up then i saw this, never forget the {get;set;} after a string property.
1

For the model-binder to catch them, they need to be named on HTML form as child properties. Depending on how you've built your view, they may not automatically be generated as such. Check your form for

<input name="_a.descendant">

If your child properties have templates and they aren't automatically employed, it might be necessary to:

@{ Html.RenderPartial("Template_A", Model._a, new ViewDataDictionary {
    TemplateInfo = new System.Web.Mvc.TemplateInfo {
         HtmlFieldPrefix = "_a"
    }
});}

1 Comment

all my properties were named with prefix "_a" or "_b"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.