2

I have a model of ClassA that has a property that is an array of ClassB.

public class ClassA
{
    public string ClassAProperty1 { get; set; }
    public string ClassAProperty2 { get; set; }
    public ClassB[] MySubCollection { get; set; }
}

public class ClassB
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
}

I'd like to edit my instances of ClassB in a table. I've created an EditorTemplate for ClassB that creates a table row.

    @model ClassB
    <tr>
        <td>@Html.TextBoxFor(m => m.Prop1)</td>
        <td>@Html.TextBoxFor(m => m.Prop2)</td>
    </tr>

This works great on the edit view for ClassA since MVC does all the field indexing magic itself:

@Html.TextBoxFor(m => m.ClassAProperty1)
@Html.TextBoxFor(m => m.ClassAProperty2)

<table>
    <tr>
        <th>Col</th>
        <th>Col</th>
    </tr>
    @Html.EditorFor(m => m.MySubCollection)
</table>

However, I'd actually like to create an editor template for the array that includes the table tag like this:

@model ClassB[]
<table>
    <tr>
        <th>Col</th>
        <th>Col</th>
    </tr>
   @foreach(var item in Model)
   {
       @Html.EditorFor(m => item)
   }
</table>

So I can simply do:

@Html.TextBoxFor(m => m.ClassAProperty1)
@Html.TextBoxFor(m => m.ClassAProperty2)
@Html.EditorFor(m => m.MySubCollection)

However, the field indexing is not applied with this approach. Is there a way I can accomplish this without having to build the textbox names myself? Being a template, I don't know the property name at the time of use.

1 Answer 1

8

I figured it out. Razor is pretty smart. Using a for loop instead of a foreach solves it:

@for (var i = 0; i < Model.Length; i++)
{
    @Html.EditorFor(c => Model[i])
}
Sign up to request clarification or add additional context in comments.

4 Comments

While this works for you, your negating one of the main benefits of using an EditorTemplate which is to be able to use @Html.EditorFor(m =>m.SomeProperty) where SomeProperty can be either a single instance of a model of a collection of models.
My template for an array of ClassB has the for loop. My view for ClassA does use @Html.EditorFor (m => m.MySubCollection).
Your not understanding my comment. One of the benefits of using an EditorTemplate is that you can pass it a single instance of ClassB or a collection of ClassB. You use means that you can no longer use EditorFor (m => m.MySubCollection) if MySubCollection is typeof ClassB - it now only works if MySubCollection is typeof IEnumerable<ClassB>
I see what you're saying, but there's really no point of an EditorTemplate building a table row if you have to always build the surrounding table and thead tags around it every time you want to use it. In this case, I guess I could improve it by abandonding the inner EditorFor and make my ClassB template something that could live outside of a table. Thus, only my ClassB[] uses a table with rows built in the loop. I'm sorry, but I can't see a practical case for using a single template for both a single instance and collection. You need to somehow control UI flow for collections.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.