ASP.NET MVC的Razor视图如何支持接收IPaginationModel<T>泛型类型参数?
报错原因
Razor视图引擎无法识别你在@model声明里写的未绑定具体类型的泛型参数T,因此抛出找不到类型命名空间的错误。
可行解决方案
方案1:使用泛型视图(仅支持.NET Core/.NET 5+)
新版本ASP.NET Core MVC的Razor支持显式声明泛型参数,你只需要在视图顶部加@typeparam声明即可:
@* 声明泛型参数及约束 *@ @typeparam T where T : class @model Solnet.TeddyPicker.Generator.Models.Pagination.IPaginationModel<T> @* 分页逻辑注意修正参数:原来的Model.PageIndex要换成lambda传入的page变量,否则点任何页码都跳当前页 *@ @Html.PagedListPager(Model.PagedCollection, page => Url.Action("Index", new { pagesize = Model.ItemsPerPage, page = page }), new X.PagedList.Web.Common.PagedListRenderOptions() { LiElementClasses = new string[] { "page-item" }, PageClasses = new string[] { "page-link" }, Display = X.PagedList.Web.Common.PagedListDisplayMode.Always })
方案2:抽取非泛型基接口(兼容所有.NET版本,更推荐)
你的分页视图本身不需要关心列表内的元素类型,只需要用到分页相关的基础属性,完全可以把泛型接口的通用逻辑抽到非泛型基接口中,彻底避免泛型参数的问题:
- 先定义非泛型分页基接口
public interface IPaginationModel { // X.PagedList自带非泛型IPagedList接口,泛型IPagedList<T>默认继承该接口 IPagedList PagedCollection { get; set; } int ItemsPerPage { get; set; } int PageIndex { get; set; } int TotalPages { get; set; } }
- 让原来的泛型接口继承该基接口
public interface IPaginationModel<T> : IPaginationModel where T : class { // 用new关键字重写泛型版本的PagedCollection属性 new IPagedList<T> PagedCollection { get; set; } }
- 视图直接声明使用非泛型基接口即可
@model Solnet.TeddyPicker.Generator.Models.Pagination.IPaginationModel @Html.PagedListPager(Model.PagedCollection, page => Url.Action("Index", new { pagesize = Model.ItemsPerPage, page = page }), new X.PagedList.Web.Common.PagedListRenderOptions() { LiElementClasses = new string[] { "page-item" }, PageClasses = new string[] { "page-link" }, Display = X.PagedList.Web.Common.PagedListDisplayMode.Always })
所有实现了泛型IPaginationModel<T>的模型都可以直接传给这个视图使用,完全满足全站复用的需求。
内容的提问来源于stack exchange,提问作者Sean T
相关产品推荐
相关产品推荐

