NameFor generates incorrect name when iterating over collection in editor template

前端 未结 1 529
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-12 03:02

Suppose I have a view typed to a collection, e.g. a List:

@model List

@for(int i = 0; i < Model.Co         


        
1条回答
  •  南笙
    南笙 (楼主)
    2021-01-12 03:27

    Why does NameFor (and therefore EditorFor) exhibit this behaviour in this particular scenario when it works fine for slight variations (i.e. is it intentional and, if so, why)?

    It is a bug (link) and it will be fixed with release of ASP.NET MVC 5.

    Is there a simple way of working around this behaviour without any of the shortcomings of the above?

    Simple:

    1. Add ItemViewModel.cshtml editor template with following code:

      @model ItemViewModel
      @Html.EditorFor(m => m.Foo)
      @Html.EditorFor(m => m.Bar) 
      
    2. Remove _ItemView.cshtml editor template.

    3. Remove [UIHint("_ItemView")] attribute from WrappingViewModel.

    A little bit harder:

    1. Add ItemViewModel.cshtml editor template (same as above).

    2. Modify _ItemView.cshtml:

      @model List
      
      @{
          string oldPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;
      
          try
          {
              ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;
      
              for (int i = 0; i < Model.Count; i++)
              {
                  var item = Model[i];
                  string itemPrefix = string.Format("{0}[{1}]", oldPrefix, i.ToString(CultureInfo.InvariantCulture));
                  @Html.EditorFor(m => item, null, itemPrefix)
              }
          }
          finally
          {
              ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
          }
      }
      

    UPDATE

    In case if you don't want to add ItemViewModel.cshtml editor template for the second option then instead of @Html.EditorFor(m => item, null, itemPrefix) you have to write something like that:

    @Html.EditorFor(m => item.Foo, null, Html.NameFor(m => item.Foo).ToString().Replace("item", itemPrefix))
    
    @Html.EditorFor(m => item.Bar, null, Html.NameFor(m => item.Bar).ToString().Replace("item", itemPrefix))
    

    NOTE: It's better to wrap that piece of code as extension method

    0 讨论(0)
提交回复
热议问题