Unable to display publisher model for nested IEnumerable

advertisements

I want to display an Article with several fields in my view but it doesn't work right: the fields doesn't show (only the header (fields' names) does).

Article class:

public class Article : IComparable
{
    public IEnumerable<ArticleField> Fields
    {
        get;
        set;
    }

    [More properties...]
}

ArticleField class:

public class ArticleField
{
    // !! I want this display in a table Header !!
    [Display(Name = "Name", ResourceType = typeof(Resources.Classes.ArticleField))]
    [Required(ErrorMessageResourceName="required", ErrorMessageResourceType=typeof(Resources.Common.Validation))]
    public string Name
    {
        get;
        set;
    }
    [More properties...]
}

Index.cshtml (appear fine to rendered html)

@model MygLogWeb.Classes.Article.Article

@using (Html.BeginForm("Index", "Article", FormMethod.Post))
{
    @Html.AntiForgeryToken()

    <table class="table">
        <tbody>

            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <td>
                    @if (Model.IsSystem)
                    {
                        @Html.HiddenFor(model => model.Name)
                        @Model.Name
                    }
                    else
                    {
                        @Html.EditorFor(model => model.Name)
                    }
                </td>
            </tr>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.IsSystem)
                </th>
                <td>
                    @Html.HiddenFor(model => model.IsSystem)
                    @Model.IsSystem
                </td>
            </tr>
        </tbody>
    </table>

    <br style="margin: 0.5em 0em;"/>

    @* POINT OF INTEREST *@
    @Html.EditorFor(model => model.Fields, "ArticleFields") 

    <button type="submit" name="button" value="save">@Resources.Common.Buttons.save</button>
}

EditorTemplates/ArticleFields.cshtml (appear fine to rendered html)

@model IEnumerable<MygLogWeb.Classes.Article.ArticleField>

@using MygLogWeb.Classes.Article

@{
    var uid = Guid.NewGuid().ToString();
    var GlobalViewBag = ViewContext.Controller.ViewBag;

    GlobalViewBag.ItemCount = Model.Count();
}

<table class="table none" id="@uid">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.IsSystem)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.IsVirtual)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Formula)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                @* POINT OF INTEREST *@
                @Html.EditorFor(model => model)
            </td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td colspan="5">
                <input type="button" value="@Resources.Common.Buttons.add" data-row-add="ArticleField" data-row-addto="#@uid > TBODY" />
            </td>
        </tr>
    </tfoot>
</table>

<script type="text/javascript">
    new TableEdit("@uid");
</script>

EditorTemplates/ArticleFields.cshtml (doesn't appear at all to rendered html)

@model MygLogWeb.Classes.Article.ArticleField

xxx

I though I could make public IEnumerable<ArticleField> Fields a List<T> but then I'll get an issue with the headers. Code such as @Html.DisplayNameFor(model => model.Formula) wouldn't work.


Instead of

@Html.EditorFor(model => model)

You must use an element of the collection

@Html.EditorFor(model => model[0])

or for loop over elements

@foreach (var item in Model)
{
    @Html.EditorFor(model => item)
}

If you are planning to post back with the same model, then you'll want to use a List rather than an IEnumerable in order for the default model binder to create your objects in the post