如何让分页Partial适配多控制器、多ViewModel及多视图场景?
通用分页Partial视图改造方案
要让分页Partial支持多控制器/视图复用,核心是把硬编码的控制器、Action以及路由参数动态化,下面是具体实现步骤:
1. 扩展分页模型(可选,提升灵活性)
修改BasePageableModel,添加路由相关属性,用于传递目标控制器、Action及额外查询参数:
public class BasePageableModel { // 原有分页属性保留 public int PageNumber { get; set; } public int PageSize { get; set; } public int TotalPages { get; set; } // 注意:原代码循环误用了PageSize,需替换为总页数TotalPages public bool HasPreviousPage { get; set; } public bool HasNextPage { get; set; } // 新增路由配置属性 public string ControllerName { get; set; } public string ActionName { get; set; } // 传递额外查询参数(如搜索关键词、分类ID等) public RouteValueDictionary RouteValues { get; set; } = new RouteValueDictionary(); }
2. 改造分页Partial视图
将硬编码的路由信息替换为模型动态值,同时保留额外参数:
@model CTA_Client.Models.BasePageableModel @if (Model.TotalPages > 1) // 总页数大于1时才显示分页 { <div class="center-block text-center"> <ul class="pagination mb-lg-0 mb-5"> <!-- 上一页 --> <li class="page-item page-prev @(Model.HasPreviousPage == false ? "disabled" : "")"> <a class="page-link" tabindex="-1" asp-controller="@Model.ControllerName" asp-action="@Model.ActionName" asp-all-route-data="@Model.RouteValues" asp-route-PageNumber="@(Model.PageNumber - 1)">Prev</a> </li> <!-- 页码列表 --> @for (int i = 1; i <= Model.TotalPages; i++) { <li class="page-item @(i == Model.PageNumber ? "active" : "")"> <a class="page-link" asp-controller="@Model.ControllerName" asp-action="@Model.ActionName" asp-all-route-data="@Model.RouteValues" asp-route-PageNumber="@i">@i</a> </li> } <!-- 下一页 --> <li class="page-item page-next @(Model.HasNextPage == false ? "disabled" : "")"> <a class="page-link" asp-controller="@Model.ControllerName" asp-action="@Model.ActionName" asp-all-route-data="@Model.RouteValues" asp-route-PageNumber="@(Model.PageNumber + 1)">Next</a> </li> </ul> </div> }
注意:原代码循环条件使用
Model.PageSize(每页条数)是逻辑错误,需改为Model.TotalPages(总页数)。
3. 父视图传递参数
根据场景选择不同的参数传递方式:
方式1:手动指定路由(跨控制器分页场景)
@Html.Partial("~/Views/Shared/_pagination.cshtml", new BasePageableModel { PageNumber = Model.PagingFilteringContext.PageNumber, PageSize = Model.PagingFilteringContext.PageSize, TotalPages = Model.PagingFilteringContext.TotalPages, HasPreviousPage = Model.PagingFilteringContext.HasPreviousPage, HasNextPage = Model.PagingFilteringContext.HasNextPage, ControllerName = "Blog", ActionName = "List", // 保留当前视图的路由参数,避免分页时丢失查询条件 RouteValues = new RouteValueDictionary(ViewContext.RouteData.Values) })
方式2:自动获取当前路由(同控制器分页场景)
如果分页跳转的是当前控制器的Action,可直接在Partial中获取路由信息,无需手动赋值模型属性:
在Partial视图顶部添加:
@{ var currentController = ViewContext.RouteData.Values["controller"].ToString(); var currentAction = ViewContext.RouteData.Values["action"].ToString(); }
然后将视图中asp-controller="@Model.ControllerName"替换为asp-controller="@currentController",asp-action="@Model.ActionName"替换为asp-action="@currentAction"即可。
4. 适配多业务模型
只要你的BlogPagingFilteringModel、ProductPagingFilteringModel等继承自BasePageableModel,并在控制器中正确赋值分页及路由属性,即可在对应视图中直接复用:
// 电商商品列表视图示例 @Html.Partial("~/Views/Shared/_pagination.cshtml", Model.PagingFilteringContext)
内容的提问来源于stack exchange,提问作者whisk
相关产品推荐
相关产品推荐

