【问题标题】:Why is my DisplayFor not looping through my IEnumerable<DateTime>?为什么我的 DisplayFor 没有循环通过我的 IEnumerable<DateTime>?
【发布时间】:2011-12-30 11:06:03
【问题描述】:

我认为这条线

@(Html.DisplayFor(m => m.DaysOfWeek, "_CourseTableDayOfWeek"))

其中m.DaysOfWeekIEnumerable&lt;DateTime&gt;

有_CourseTableDayOfWeek.cshtml的内容:

@model DateTime
@{
    ViewBag.Title = "CourseTableDayOfWeek";
}
<th>
    @System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int) Model.DayOfWeek]
    <span class="dateString">Model.ToString("G")</span>
</th>

我收到以下错误:

传入字典的模型项的类型为“System.Collections.Generic.List`1[System.DateTime]”,但该字典需要类型为“System.DateTime”的模型项。

如果我参考以下帖子:

https://stackoverflow.com/a/5652524/277067

DisplayFor 应该循环遍历 IEnumerable 并显示每个项目的模板,不是吗?

【问题讨论】:

    标签: asp.net-mvc-3 view


    【解决方案1】:

    它没有循环,因为您已将显示模板的名称指定为 DisplayFor 助手 (_CourseTableDayOfWeek) 的第二个参数。

    只有当你依赖约定时它才会循环,即

    @Html.DisplayFor(m => m.DaysOfWeek)
    

    然后在~/Views/Shared/DisplayTemplates/DateTime.cshtml:

    @model DateTime
    @{
        ViewBag.Title = "CourseTableDayOfWeek";
    }
    <th>
        @System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int) Model.DayOfWeek]
        <span class="dateString">Model.ToString("G")</span>
    </th>
    

    一旦您为显示模板指定了自定义名称(作为 DisplayFor 帮助程序的第二个参数或作为 [UIHint] 属性),它将不再循环收集属性,并且模板将简单地传递 IEnumerable&lt;T&gt; 作为模型.

    这很令人困惑,但事实就是如此。我也不喜欢。

    【讨论】:

    • 同上。这些帮助程序的另一个方面是难以调试且完全不清楚。
    • 我刚刚落入了同一个陷阱。这对我来说似乎完全违反直觉。我希望这会随着 MVC 4 改变。
    • @JohnH 它没有改变。在 MVC 5 中仍然以这种方式工作。
    【解决方案2】:

    这似乎是一个错误。 Html Helper 类很容易扩展,尽管在查看了 MVC 源代码并寻找错误之后,我放弃了,只是利用了模板适用于单个项目的前提,所以我编写了一个 HtmlHelper 扩展来为你包装它。为了我自己的简单性,我取出了 lambda 表达式,但你可以很容易地回到那个。此示例仅适用于字符串列表。

        public static class DisplayTextListExtension
    {
        public static MvcHtmlString DisplayForList<TModel>(this HtmlHelper<TModel> html, IEnumerable<string> model, string templateName)
        {
            var tempResult = new StringBuilder();
    
            foreach (var item in model)
            {
                tempResult.Append(html.DisplayFor(m => item, templateName));
            }
    
            return MvcHtmlString.Create(tempResult.ToString());
        }
    }
    

    那么实际用法是这样的:

                                    @Html.DisplayForList(Model.Organizations, "infoBtn")
    

    【讨论】:

      【解决方案3】:

      一个小调整,让 Dan's solution 更通用一点:

      public static class DisplayTextListExtension
          {
              public static MvcHtmlString DisplayForList<TModel, 
      EModel>(this HtmlHelper<TModel> html, IEnumerable<EModel> model, string templateName)
              {
                  var tempResult = new StringBuilder();
      
                  foreach (var item in model)
                  {
                      tempResult.Append(html.DisplayFor(m => item, templateName));
                  }
      
                  return MvcHtmlString.Create(tempResult.ToString());
              }
          }
      

      【讨论】:

        【解决方案4】:

        IEnumerable&lt;T&gt; 属性上使用FilterUIHint 而不是常规的UIHint

        public class MyModel
        {
            [FilterUIHint("_CourseTableDayOfWeek")]
            public IEnumerable<DateTime> DaysOfWeek { get; set; }
        }
        

        不需要其他任何东西。

        @Html.DisplayFor(m => m.DaysOfWeek)
        

        这会为DaysOfWeek 中的每个DateTime 显示一个"_CourseTableDayOfWeek" EditorTemplate。

        【讨论】:

        • 我无法让它工作。它只是忽略了FilterUIHint,就像没有注释一样。您还使用了 DisplayFor 但每个都说 EditorTemplate;这是一个错误还是故意的?
        猜你喜欢
        • 2019-09-16
        • 2017-03-13
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 2020-01-13
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        相关资源
        最近更新 更多