编辑器集合和命名模板
本文关键字:集合 编辑器 | 更新日期: 2023-09-27 18:04:19
我是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的编辑器模板,它看起来像这样:
@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")
得到这个错误:
模板只能用于字段访问、属性访问、一维数组索引或带有单个参数的自定义indexerausdrcken。
如果我转换的ICollection在我的模型到一个列表,它工作完美。但是这是一个从实体框架生成的类,所以这里的改变会破坏EF的功能。
我认为这是命名模板的一个特殊问题。因为如果我做一个默认的编辑模板为一个单一的过滤器称为过滤器。CSHTML和调用
@Html.EditorFor(m => m.Filters)
ICollection在内部处理得很好,EditorFor为List中的每个对象调用Template。
但是一定有解决这个问题的办法。唯一有效的方法是将Template更改为
@model ICollection<Filter>
@Html.EditorFor(modelItem => @Model.ToList()[i].isRemoveable)
然后这样命名
@Html.EditorFor(m => m.Filters, "FiltersCustomEditor")
但是我认为这确实是一个弱的解决方案,特别是对于性能,如果每个字段必须在访问之前将iccollection转换为List。
所以他们是一种解决方法还是我错过了什么?
您将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(没有循环,没有传递集合等)
旁注:根据您的评论,您还可以在/Views/YourControllerName/EditorTemplates
文件夹中放置与每个控制器相关的特定EditorTemplates
。默认情况下,EditorFor()
方法将首先搜索/Views/YourController/EditorTemplates
。如果没有找到,它将搜索/Views/Shared/EditorTemplates
。最后,如果没有找到,它将使用内置的默认模板(s)基于您的模型属性。