我是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.IList
1 [Filter]”。]
所以我试着这样称呼它:
@Html.EditorFor(m => m.Filters.ToList(), "FiltersCustomEditor")
并收到此错误:
模板只能与字段访问,属性访问,一维数组索引或带有单个参数的自定义Indexerausdrücken一起使用。
如果我将模型中的ICollection转换为List,它可以完美运行。但这是来自实体框架的生成类,因此这里的更改会破坏EF功能。
我认为这是命名模板的一个特殊问题。因为如果我为名为Filter.cshtml的单个过滤器创建一个默认的EditorTemplate并调用
@Html.EditorFor(m => m.Filters)
ICollection很好地处理,编辑器为列表中的每个对象调用模板。
但他们必须解决这个问题。唯一有效的方法是将模板更改为
@model ICollection<Filter>
@Html.EditorFor(modelItem => @Model.ToList()[i].isRemoveable)
并像这样称呼它
@Html.EditorFor(m => m.Filters, "FiltersCustomEditor")
但我认为,如果每个字段必须在访问之前将ICollection转换为List,那么这绝对是一个弱解决方案,特别是性能。
他们是一种解决方法,还是我错过了什么?
答案 0 :(得分:1)
您将ICollection<Filter>
传递给模板,但模板中的模型为IList<Filter>
,因此错误(ICollection<T>
不是IList<T>
)。但是你的方法不正确。 EditorFor()
方法接受IEnumerable<T>
,因此代码可以简化为
在/Views/Shared/EditorTemplates/Filter.cshtml
中(注意模板的名称必须与类的名称相同)
@model yourAssembly.Filter
@Html.CheckBoxFor(m => m.isRemoveable)
.... // add any other properties, labels etc of Filter
然后在主视图中它只是
@model yourAssembly.Product
@using (Html.BeginForm())
{
....
@Html.EditorFor(m => m.Filters)
}
EditorFor()
方法将根据模板(没有循环,没有传递集合等)为集合中的每个项目正确生成html。
附注:除了您的评论之外,您还可以在EditorTemplates
文件夹中放置与每个控制器相关的特定/Views/YourControllerName/EditorTemplates
。默认情况下,EditorFor()
方法将首先搜索/Views/YourController/EditorTemplates
。如果找不到,则会搜索/Views/Shared/EditorTemplates
。最后,如果找不到一个,它将根据您的模型属性使用内置的默认模板。