编辑IC50lection和命名模板

时间:2015-07-23 12:14:51

标签: c# asp.net-mvc templates editorfor icollection

我是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,那么这绝对是一个弱解决方案,特别是性能。

他们是一种解决方法,还是我错过了什么?

1 个答案:

答案 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。最后,如果找不到一个,它将根据您的模型属性使用内置的默认模板。