Search code examples
asp.netasp.net-mvcasp.net-mvc-4razorengine

MVC nested EditorTemplate with Html.BeginCollectionItem extension always returns an object with values set to '0' or 'null'


I am trying to return a model which contains one or more sub-models which, in turn, can also contain a sub-model. The first layer returns succesfully, however, when I want to return the 3rd layer of sub-model, I get a 'default' instance of that model without the actually filled in variables. So, the model returned contains a sub-model and the sub-model contains another sub-model, but that last sub-model's values are set to '0' and 'null'.

I am using the Html.BeginItemCollection extension methods, but I am unsure if I am using them in the correct way at layer 3. If someone would please take a look at this and help me out?

Main model page (layer 1)

@using Website.Models
@model CreateAgendaBindingModel
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
    <div class="form-horizontal">   
    for (int i = 1; i < 16; i++)
    {
        <div id='CreateVoedingDiv_@i'>
              @Html.EditorFor(x => x.VoedingCollection[i], "CreateVoedingTemplate")
        </div>
    }
}

Main model class (layer 1)

public class CreateAgendaBindingModel
{
    public int Id { get; set; }
    public List<CreateVoedingBindingModel> VoedingCollection { get; set; }
}

Sub-model page (layer 2)

@using HtmlHelpers.BeginCollectionItem;
@using Website.Models

@model CreateVoedingBindingModel

@using (Html.BeginCollectionItem("VoedingCollection"))
{
    <div class="form-group" id=@customVoedingId>
            @Html.EditorFor(x => x.CustomVoeding[0], "CreateCustomVoedingTemplate")
    </div>
}

Sub-model class (layer 2)

public class CreateVoedingBindingModel
{
    public int Id { get; set; }
    public List<customvoeding> CustomVoeding { get; set; }
}

Sub-model of sub-model page (layer 3)

@using HtmlHelpers.BeginCollectionItem;
@model FoodtrackerModel.customvoeding

@using (Html.BeginCollectionItem(ViewData.TemplateInfo.HtmlFieldPrefix + ".CustomVoeding"))
{
    <div class="form-group">
        @Html.Label("Opmerking (optioneel)", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.customVoedingOpmerking, new { htmlAttributes = new { @class = "form-control" } })                   
        </div>
    </div>
}

The sub-model of sub-model class is a partial class which is integrated with Entity Framework.

Sub-model of sub-model class (layer 3)

public partial class customvoeding
{
    public static List<customvoeding> GetAllCustomvoeding()
    {
        using (foodtrackerEntities1 db = new foodtrackerEntities1())
        {
            db.Configuration.LazyLoadingEnabled = false;
            return db.customvoeding.ToList();
        }
    }
}

So to clarify, layer 1 and 2 are returned with all variables filled in. Layer 3 is returned but no variables are filled in.


Solution

  • I solved my issue by not using a sub-model of a sub-model. I just simply hardcoded the sub-model of the sub-model fields as fields to the previous layer (so layer 3 fields became layer 2 fields). Disgusting, but it solved my problem. I honestly did not understand the solution provided in a quick timeframe and since time is money, I went on.

    Dissappointed that MVC does not have this functionality by default.