0

I have two objects that I pass to View, and than back to controller.

public class Category1Dictionary
{
    public int Id { get; set; }
    public IList<Category2Dictionary> SubCategories {get; set;}
    public string UserName { get; set; }
}

public class Category2Dictionary
{
    public int Id { get; set; }
    public string Category2Item { get; set; }
}

My view looks like this:

@model Budget.Models.Category1Dictionary
@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div class="form-horizontal">
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(m => m.Id)
    @Html.HiddenFor(m => m.UserName)
    @Html.HiddenFor(m => m.SubCategories)


    @Html.LabelFor(m => m.Category1Item, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="form-group">

    <div class="col-md-10">
        @Html.EditorFor(m => m.Category1Item, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(m => m.Category1Item, "", new { @class = "text-danger" })
    </div>
    @for (int i = 0; i < Model.SubCategories.Count; i++)
    {
        <div class="col-md-10" style="padding-left:40px">
            @Html.EditorFor(m => m.SubCategories[i].Category2Item, new { htmlAttributes = new { @class = "form-control" } })
            @Html.HiddenFor(m => m.SubCategories[i].Id, new { htmlAttributes = new { @class = "form-control" } })
        </div>
    }
</div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Save" class="btn btn-default" />
        </div>
    </div>
</div>
}

And action in the controller:

[HttpPost]
public ActionResult Edit(Category1Dictionary category1Dictionary)
{
   return View(category1Dictionary);
}

With this layout in action I get object Category1Dictionary with all items but SubCategories is NULL. I saw some similar posts but I have spent 6 hours in total on this and still can make it work...

Get Method:

public ActionResult Edit(int? id)
{
   if (id == null)
   {
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
   }
Category1Dictionary category1Dictionary = db.Category1Dictionaries.Include(p=>p.SubCategories).First(c=>c.Id == id);

if (category1Dictionary == null)
  {
     return HttpNotFound();
  }
return View(category1Dictionary);
}

EDIT: input field generated by EditorFor enter image description here

Post message from fiddler: enter image description here

Piotr P
  • 294
  • 1
  • 4
  • 12
  • 1
    Please Include your HttpGet Method? I want to check something – Mosia Thabo Apr 19 '20 at 17:24
  • 1
    Because your HTML Is using category1Dictionary values, meaning that on first load (get load), it's expecting data. That is before you could even think of submitting that post form. – Mosia Thabo Apr 19 '20 at 17:25
  • Yes it is using category1Dictionary, but page is loading properly, I have this values from list printed on the site. Till the post action everything is working fine. – Piotr P Apr 19 '20 at 17:31
  • 1
    You might want to look at this: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-3.1#collections – Mosia Thabo Apr 19 '20 at 17:52
  • Does this answer your question? [MVC post a list of complex objects](https://stackoverflow.com/questions/26155607/mvc-post-a-list-of-complex-objects) – Mosia Thabo Apr 19 '20 at 18:03
  • I tried the first solution, I set Id and Name to "Subcategories[i].Category2Item", but it didn`t work, I am not sure what name supposed to be set on – Piotr P Apr 19 '20 at 18:15
  • 1
    Ok two things... Can you remove `@Html.HiddenFor(m => m.SubCategories)` and try again? Because when this line is there, it means subCategories will bind from it as well, which may be null(you can check the generated HTML for it to confirm). – Mosia Thabo Apr 19 '20 at 18:20
  • 1
    Because with your current code, I am not sure if binding prioritizing binding each item generated from the loop or it's binding that hidden field... But the generated Inputs are done correctly and it's supposed to work – Mosia Thabo Apr 19 '20 at 18:22
  • Ok, sadly removing this do not change anything, but i added post message from fillder, maybe it will help – Piotr P Apr 19 '20 at 18:30
  • This "System.Collections.Generic.List`1[Budget.Models.Category2Dictionary]" part looks disturbing – Piotr P Apr 19 '20 at 18:31
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/212024/discussion-between-mosia-thabo-and-piotr-p). – Mosia Thabo Apr 19 '20 at 18:43
  • Thank you for help. To be honest It turned out that removing @Html.HiddenFor(m => m.SubCategories) worked. (I had it in two places, of which one i had removed in this post in order to have clean code) – Piotr P Apr 19 '20 at 19:00
  • Okay, because I was thinking that it might be binding collision somewhere, where by `@Html.HiddenFor(m => m.SubCategories)` overwrites everything... Hence I thought removing it seems to be the way forward. – Mosia Thabo Apr 19 '20 at 19:04
  • I am happy for you, atleast you can now save the time and do something else. Good Luck! :) – Mosia Thabo Apr 19 '20 at 19:08

0 Answers0