【发布时间】:2015-07-23 12:14:51
【问题描述】:
我是 MVC 5 和 ASP.NET、EF6 的新手,现在我遇到了一个名为 EditorTemplate 的问题。
我的模型如下所示:
public partial class Product
{
public int pid { get; set; }
public string Name { get; set; }
public virtual ICollection<Filter> Filters{ get; set; }
}
public partial class Filter
{
public bool isRemoveable { get; set; }
}
我有一个名为 FiltersCustomEditor 的 EditorTemplate,看起来像这样:
@model IList<Filter>
@Html.EditorFor(modelItem => @Model[i].isRemoveable)
我现在的问题是在我的产品视图中我无法调用:
@Html.EditorFor(m => m.Filters, "FiltersCustomEditor")
我收到此错误:
已传递给字典的模型元素的类型为“System.Collections.Generic.HashSet
1[Filter]". However, this dictionary requires a model item of type "System.Collections.Generic.IList1[Filter]”。]
所以我试着这样称呼它:
@Html.EditorFor(m => m.Filters.ToList(), "FiltersCustomEditor")
并得到这个错误:
模板只能与字段访问、属性访问、一维数组索引或带有单个参数的自定义 Indexerausdrücken 一起使用。
如果我将模型中的 ICollection 转换为列表,它会完美运行。但这是从 Entity Framework 生成的类,因此此处的更改会破坏 EF 功能。
我认为这是命名模板的一个特殊问题。因为如果我为名为 Filter.cshtml 的单个过滤器创建默认 EditorTemplate 并调用
@Html.EditorFor(m => m.Filters)
ICollection 在内部得到很好的处理,EditorFor 为列表中的每个对象调用模板。
但是他们必须是这个问题的解决方案。唯一可行的是将模板更改为
@model ICollection<Filter>
@Html.EditorFor(modelItem => @Model.ToList()[i].isRemoveable)
然后这样称呼它
@Html.EditorFor(m => m.Filters, "FiltersCustomEditor")
但我认为这确实是一个弱解决方案,特别是性能方面,如果每个字段都必须在访问之前将 ICollection 转换为 List。
那么他们是一种解决方法还是我错过了什么?
【问题讨论】:
-
您的属性是
ICollection<Filter>,但您的视图是@model IList<Filter>。它们不是同一件事。您需要更改其中之一。但正确的方法是将您的模板命名为/Views/Shared/EditorTemplates/Filter.cshtml并使用@Html.EditorFor(m => m.Filters),其中模板为@model Filter并包含EditorFor(m =>m.isRemoveable) -
是的,这行得通,但是如果我想要一个过滤器列表的自定义编辑器怎么办?特别是如果我想要多个过滤器编辑器?有没有办法将 EditorFor ICollection 的 linq 表达式作为列表给出?
-
对不起,我不明白您的评论 - 如果模板被命名为与模型匹配并且有
@model Filter和@EditorFor(m =>m.isRemoveable)那么它是一个模板,可以用于呈现集合(通过在主视图中使用@Html.EditorFor(m => m.Filters))。这就是编辑器模板的设计方式。如果您想要多个过滤器,您可以在Views/YourController/EditorTemplates/Filter.cshtm添加更具体的过滤器,以便您可以为每个控制器使用不同的模板 -
不,你不能将
ICollection<T>传递给期望IList<T>的东西,反之亦然 -
啊,这是一个很好的观点:Views/YourController/EditorTemplates/Filter.cshtm。我不知道每个控制器都有 EditorTemplates,我认为它们必须始终共享。然后使用单元素模板的方法适合我的需要。非常感谢
标签: c# asp.net-mvc templates editorfor icollection