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?
 
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
 
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
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
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
 
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:
Using EditorFor solved the problem.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.