C# Razor beginform binding nested object in view and post it all back to controller

I have a view model like this:
namespace MySystem.Models.View {
   public class ItemPage {
      public Item Item { get; set; }
      public int CurrentItemID { get; set; }
      public string ModalHeading { get; set; }
      public string SubmitButtonText { get; set; }
      /// <summary>
      /// This will be the color that we will use in the view, if set
      /// </summary>
      public System.Drawing.Color CssColorTwist { get; set; }
      public ItemPage() {
         //ItemEngine iEngine = new ItemEngine();
         //this.Item = iEngine.GetItem(CurrentItemID);
      }
      public ItemPage(Item item) {
         this.Item = item;
         this.CurrentItemID = Item.ItemID;
      }
      public ItemPage(Item item, string btnText, string modalHeading) {
         this.Item = item;
         ModalHeading = modalHeading;
         SubmitButtonText = btnText;
         this.CurrentItemID = Item.ItemID;
      }
      public ItemPage(Item item, string btnText, string modalHeading, System.Drawing.Color cssColor) {
         this.Item = item;
         ModalHeading = modalHeading;
         SubmitButtonText = btnText;
         CssColorTwist = cssColor;
         this.CurrentItemID = Item.ItemID;
      }
      public Color GetCssColorDarker(double factor) {
         if(CssColorTwist != null) {
            return CssColorTwist.GetColorDarker(factor);
         }
         return new Color();         
      }
      public Color GetCssColorLighter(double factor) {         
         if (CssColorTwist != null) {
            return CssColorTwist.GetColorLighter(factor);
         }
         return new Color();
      }
   }
}

Open in new window


I want to bind and set the nested item properties in the view like this:
<span class="display-form-item">@Html.DisplayNameFor(model => model.Item.Address):</span>
@Html.TextBoxFor(model => model.Item.Address, new { @id = "addressID-" + @Model.Item.ItemID, @class = "form-control", data_toggle = "tooltip", data_placement = "bottom", @title = "Skriv inn adresse" })
@Html.ValidationMessageFor(model => model.Item.Address, String.Empty, new { @class = "alert-danger" })

Open in new window


When posting to the controller, all the properties of the view model end up as null. If I remove the nested object Item from the view model and remove all bindings to that nested object in the view, then all works good, all other properties are set.

So the problem is, how to bind nested object properties in the Item object in the view and post back to the controller with the model and nested object and all?
LVL 2
itniflAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Prakash SamariyaIT ProfessionalCommented:
Ideally, ViewModel with nested object works fine in MVC!  

You might missing some steps, please check in controller, when you get ItemPage object initialised, check for Item object as well if it is initialised or not!! If Item object is null, then in views, it end up.

If not works, please paste snapshot of error and controller code as well to look into that as well
0
käµfm³d 👽Commented:
What does the name attribute of the textbox show in the rendered HTML?
0
itniflAuthor Commented:
The controller is irrelevant here, but here it is:
      [Authorize(Roles = "Admin")]
      [HttpPost]
      public ActionResult SaveItemInItemPage(ItemPage item) {
         ItemEngine iEngine = new ItemEngine();
         iEngine.UpdateItem(item.Item);
         return Redirect(Request.UrlReferrer.AbsoluteUri);
      }

Open in new window

ItemPage shall already have been initialized when received by the controller method with the values input by the user in the view via the bindings there.

The whole view looks like this. Bare in mind that this is only a test under construction. I have squared the name with a red box in the picture.

View result
There is no error message. As stated in the question, all properties of the model end up as null when received by the controller (verified via debugging at runtime in Visual Studio) unless I remove the Item object bindings from the view and remove the Item object from the model. In short; it works, the properties are populated by the user input, as long as I don't use a nested object as a property (the Item object). But that is what I want to do.
0
Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

käµfm³d 👽Commented:
What is the answer to my question?
0
itniflAuthor Commented:
Sorry, misunderstood you. Looks like this:
<div class="form-group custom-line-rowheight">
	<span class="display-form-item">Adresse:</span>
	<input class="form-control" data-placement="bottom" data-toggle="tooltip" id="addressID-1" name="Item.Address" title="Skriv inn adresse" type="text" value="">
	<span class="field-validation-valid alert-danger" data-valmsg-for="Item.Address" data-valmsg-replace="true"></span>
</div>

Open in new window


Or like this:

<div class="form-group">
	<span class="display-form-item">Beskrivelse:</span>
	<textarea class="form-control input-lg" cols="20" data-placement="bottom" data-toggle="tooltip" id="infoID-1" name="Item.Description" rows="2" title="Skriv beskrivelse">Dette er en flott hytte med fyrtårn!</textarea>
	<span class="field-validation-valid alert-danger" data-valmsg-for="Item.Description" data-valmsg-replace="true"></span>
</div>

Open in new window


So in these examples the names are:
  • Item.Address
  • Item.Description
0
itniflAuthor Commented:
I ended up with writing a partialview that acted as editor for Item, then I used @Html.EditorFor(model => model.Item) to display the view. That worked.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
itniflAuthor Commented:
Using EditorFor solved the problem.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.