title: Why does Razor view add "CS$<>8__locals1" prefix to input names when accessing indexer of model assigned to local variable?
body: <p>I'm building a simple ASP.NET MVC 5.2.3.0 view that displays a user name and a checkbox list of roles. You can check or uncheck the checkboxes to control which roles the user is in. Here is my ViewModel:</p>
  
  <pre><code>public class EditUserVM
  {
      public string Id { get; set; }
      public string UserName { get; set; }
      public List&lt;UserRoleVM&gt; Roles { get; set; }
  }
  
  public class UserRoleVM
  {
      public string RoleId { get; set; }
      public string RoleName { get; set; }
      public bool IsMember { get; set; }
  }
  </code></pre>
  
  <p>And it's displayed like this:</p>
  
  <pre><code>@model  VMContainer&lt;EditUserVM&gt;
  
  @* omitted for exmaple *@
  
  var userVM = Model.ViewModel;
  &lt;div class="panel panel-primary"&gt;
      &lt;div class="panel-heading"&gt;&lt;h4 style="display:inline"&gt;User: @userVM.UserName&lt;/h4&gt;&lt;/div&gt;
  
      &lt;div class="panel-body"&gt;
          @Html.ValidationSummary(false, "", new { @class = "text-danger" })
  
          &lt;h4&gt;Users Roles&lt;/h4&gt;
  
          @using (Html.BeginForm())
          {
              @Html.AntiForgeryToken()
  
              &lt;div class="form-horizontal"&gt;
                  @Html.HiddenFor(m =&gt; userVM.Id)
                  @Html.HiddenFor(m =&gt; userVM.UserName)
  
                  &lt;table class="table table-bordered table-striped"&gt;
                      &lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Role&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
                      &lt;tbody&gt;
                          @for (int x = 0; x&lt;userVM.Roles.Count; x++){
                              &lt;tr&gt;
                                  &lt;td&gt;
                                      @Html.HiddenFor(m =&gt; userVM.Roles[x].RoleId)
                                      @Html.CheckBoxFor(m =&gt; userVM.Roles[x].IsMember)
                                  &lt;/td&gt;
                                  &lt;td&gt;@Html.DisplayFor(m =&gt; userVM.Roles[x].RoleName)&lt;/td&gt;
                              &lt;/tr&gt;
                          }
                      &lt;/tbody&gt;
                  &lt;/table&gt;
  
                  &lt;div&gt;
                      &lt;input type="submit" value="Save" class="btn btn-success" /&gt;
                      @Html.ActionLink("Cancel", "Users", null, new { @class = "btn btn-default" })
                  &lt;/div&gt;
              &lt;/div&gt;
          }
  </code></pre>
  
  <p>Notice the model type is VMContainer. This is a wrapper used by my views so that in case there is an error generating the inner T ViewModel, it can display an error instead of the normal view content. To make it easier to access the EditUserVM and because that is all I need to submit, not the VMContainer wrapper, I assign it to a local variable <code>var userVM = Model.ViewModel;</code>. I've used this pattern a lot in previous projects. The problem is when I inspect the page in developer tools, all of my inputs are named wrong. They all get a prefix for what looks like a generated class. For example, <code>@Html.HiddenFor(m =&gt; userVM.Id)</code> renders:</p>
  
  <p>Through trial and error, I narrowed this down to not happening if I remove the <code>for</code> loop. That is with the <code>for</code> loop commented out, the remaining inputs are named correctly. Through further trial and error I discovered that what really triggers it is accessing the Roles indexer using a variable. E.G. If I remove the loop and just do this, it produces the wrong name for all of the inputs:</p>
  
  <pre><code>                @Html.HiddenFor(m =&gt; userVM.Id)
                  @Html.HiddenFor(m =&gt; userVM.UserName)
                  @{ int x = 0; }
                  @Html.HiddenFor(m =&gt; userVM.Roles[x].RoleId);
  </code></pre>
  
  <p>It does not generate the wrong names if I use the constant <code>[0]</code> in place of <code>[x]</code> <em>or</em> <code>m.ViewModel.Roles[x]</code> instead of <code>userVM.Roles[x]</code>. So to try to spell it out completely, it seems to occur when accessing the indexer of a local variable's descendant using a variable for the index parameter.</p>
  
  <p>I found this or something similar acknowledged for MVC 6 (at the time) but I don't understand the problem. I'm a little surprised this still exists if it is in fact a bug. Although it's hard to describe, it doesn't seem like it would be a totally uncommon scenario. Can someone explain what is going on and hopefully offer a fix? I prefer to only post an EditUserVM to my action when the form submits.</p>