Razor视图中使用IGrouping报错:未引用System.Core程序集如何解决?
在控制器中通过Linq的GroupBy实现数据分组,代码如下:
model.aLstProducts = result[0].Results .Where(c => c.Id == ProductId) .ToList() .FirstOrDefault() .ListOfProducts .GroupBy(c => c.ProductCategory);
对应的模型属性定义:
public IEnumerable<IGrouping<string, ProductsViewModel>> aLstProducts { get; set; }
但在Razor视图中执行遍历:
@foreach (var item in Model.aLstProducts) { }
抛出异常:
The type 'IGrouping<,>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
异常原因
IGrouping<TKey, TElement>是Linq分组操作的核心返回类型,它定义在System.Core程序集中。控制器编译时会自动引用该程序集,但Razor视图的编译环境默认未显式添加对System.Core的引用,导致视图无法识别这个接口类型,从而抛出异常。而泛型List能正常使用,是因为其所在的mscorlib程序集属于默认引用范畴。
解决方法
方法一:给Razor视图添加System.Core程序集引用
找到项目中Views目录下的Web.config(非项目根目录的Web.config),在<system.web.webPages.razor>节点下的<assemblies>区块中,添加System.Core的引用:
<assemblies> <!-- 保留已有引用 --> <add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </assemblies>
添加完成后重新编译项目,视图即可正常识别IGrouping类型。
方法二:转换分组结果为已识别的集合类型
若不想修改Web.config,可在控制器中将GroupBy的结果转换为Razor已支持的集合类型,比如List<KeyValuePair<string, List<ProductsViewModel>>>:
修改控制器代码:
model.aLstProducts = result[0].Results .Where(c => c.Id == ProductId) .ToList() .FirstOrDefault() .ListOfProducts .GroupBy(c => c.ProductCategory) .Select(g => new KeyValuePair<string, List<ProductsViewModel>>(g.Key, g.ToList())) .ToList();
同时更新模型的属性定义:
public List<KeyValuePair<string, List<ProductsViewModel>>> aLstProducts { get; set; }
此时视图遍历的是默认已支持的泛型集合类型,不会再出现引用异常。
内容的提问来源于stack exchange,提问作者user8512043

