title: Correct, idiomatic way to use custom editor templates with IEnumerable models in ASP.NET MVC
body: <blockquote>
    <p><em>This question is a follow-up for <a href="https://stackoverflow.com/q/8678802/11683">Why is my DisplayFor not looping through my IEnumerable&lt;DateTime&gt;?</a></em></p>
  </blockquote>
  
  <hr>
  
  <p>A quick refresh.</p>
  
  <p>When:</p>
  
  <ul>
  <li>the model has a property of type <code>IEnumerable&lt;T&gt;</code></li>
  <li>you pass this property to <code>Html.EditorFor()</code> using the overload that only accepts the lambda expression</li>
  <li>you have an editor template for the type <code>T</code> under Views/Shared/EditorTemplates</li>
  </ul>
  
  <p>then the MVC engine will automatically invoke the editor template for each item in the enumerable sequence, producing a list of the results.</p>
  
  <p>E.g., when there is a model class <code>Order</code> with property <code>Lines</code>:</p>
  
  <pre><code>public class Order
  {
      public IEnumerable&lt;OrderLine&gt; Lines { get; set; }
  }
  
  public class OrderLine
  {
      public string Prop1 { get; set; }
      public int Prop2 { get; set; }
  }
  </code></pre>
  
  <p>And there is a view Views/Shared/EditorTemplates/OrderLine.cshtml:</p>
  
  <pre><code>@model TestEditorFor.Models.OrderLine
  
  @Html.EditorFor(m =&gt; m.Prop1)
  @Html.EditorFor(m =&gt; m.Prop2)
  </code></pre>
  
  <p>Then, when you invoke <code>@Html.EditorFor(m =&gt; m.Lines)</code> from the top-level view, you will get a page with text boxes for each order line, not just one.</p>
  
  <hr>
  
  <p>However, as you can see in the linked question, this only works when you use that particular overload of <code>EditorFor</code>. If you provide a template name (in order to use a template that is not named after the <code>OrderLine</code> class), then the automatic sequence handling will not happen, and a runtime error will happen instead.</p>
  
  <p>At which point you will have to declare your custom template's model as <code>IEnumebrable&lt;OrderLine&gt;</code> and manually iterate over its items in some way or another to output all of them, e.g.</p>
  
  <pre><code>@foreach (var line in Model.Lines) {
      @Html.EditorFor(m =&gt; line)
  }
  </code></pre>
  
  <p>And that is where problems begin.</p>
  
  <p>The HTML controls generated in this way all have same ids and names. When you later POST them, the model binder will not be able to construct an array of <code>OrderLine</code>s, and the model object you get in the HttpPost method in the controller will be <code>null</code>.<br>
  This makes sense if you look at the lambda expression - it does not really link the object being constructed to a place in the model from which it comes.</p>
  
  <p>I have tried various ways of iterating over the items, and it would seem the only way is to redeclare the template's model as <code>IList&lt;T&gt;</code> and enumerate it with <code>for</code>:</p>
  
  <pre><code>@model IList&lt;OrderLine&gt;
  
  @for (int i = 0; i &lt; Model.Count(); i++)
  { 
      @Html.EditorFor(m =&gt; m[i].Prop1)
      @Html.EditorFor(m =&gt; m[i].Prop2)
  }
  </code></pre>
  
  <p>Then in the top-level view:</p>
  
  <pre><code>@model TestEditorFor.Models.Order
  
  @using (Html.BeginForm()) {
      @Html.EditorFor(m =&gt; m.Lines, "CustomTemplateName")
  }
  </code></pre>
  
  <p>which gives properly named HTML controls that are properly recognized by the model binder on a submit.</p>
  
  <hr>
  
  <p>While this works, it feels very wrong.</p>
  
  <p><strong>What is the correct, idiomatic way to use a custom editor template with <code>EditorFor</code>, while preserving all the logical links that allow the engine to generate HTML suitable for the model binder?</strong></p>