You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC(EF6):如何用Razor语法在视图中实现模型数据分页(无需控制器方法)

嘿,我来给你捋捋这个纯Razor视图内实现分页的方案——完全不用额外调用控制器方法,全靠模型带的数据搞定,刚好我之前做过类似的需求,给你一步步拆解:

核心思路说明

要实现纯视图内的分页,关键是让控制器提前把分页所需的所有数据封装到视图模型里,视图只负责用Razor语法基于模型数据渲染列表和分页导航,全程不用主动调用控制器方法。


1. 先准备分页视图模型

首先定义一个泛型的分页视图模型,这样能复用在不同实体的分页场景里:

public class PagedViewModel<T>
{
    // 当前页要展示的数据列表
    public List<T> Items { get; set; }
    // 数据库中该实体的总记录数
    public int TotalItems { get; set; }
    // 每页显示的条目数量
    public int PageSize { get; set; }
    // 当前页码
    public int CurrentPage { get; set; }

    // 视图内自动计算总页数(不用控制器传,直接用模型属性计算)
    public int TotalPages => (int)Math.Ceiling((double)TotalItems / PageSize);
}

2. 控制器提前处理分页逻辑(仅做数据准备)

虽然视图里不调用控制器方法,但控制器需要先把分页后的数据和参数装进上面的模型,再传给视图。这里用EF6的Skip+Take实现分页,注意必须先排序再分页,否则结果不稳定:

public ActionResult Index(int? page)
{
    // 处理页码默认值,避免空值或非法值
    int currentPage = page ?? 1;
    int pageSize = 10; // 可根据需求调整,也可做成配置项

    // EF6分页查询:先排序,再跳过前面的条目,取当前页的数量
    var entityQuery = db.YourTargetEntities.OrderBy(x => x.Id); // 必须排序!
    int totalItems = entityQuery.Count();
    var pagedItems = entityQuery.Skip((currentPage - 1) * pageSize)
                                .Take(pageSize)
                                .ToList();

    // 封装分页模型
    var viewModel = new PagedViewModel<YourTargetEntity>
    {
        Items = pagedItems,
        TotalItems = totalItems,
        PageSize = pageSize,
        CurrentPage = currentPage
    };

    return View(viewModel);
}

3. Razor视图内实现分页渲染

现在视图只需要基于模型数据,用Razor语法渲染列表和分页导航即可,全程不用调用控制器方法:

3.1 指定视图模型类型

@model PagedViewModel<YourTargetEntity>

3.2 渲染数据列表

<div class="data-container">
    <h3>数据列表</h3>
    <table class="table table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>名称</th>
                <th>创建时间</th>
                <!-- 其他字段根据实际需求添加 -->
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Items)
            {
                <tr>
                    <td>@item.Id</td>
                    <td>@item.Name</td>
                    <td>@item.CreateTime.ToString("yyyy-MM-dd")</td>
                </tr>
            }
        </tbody>
    </table>
</div>

3.3 渲染分页导航(核心部分)

这里直接用Razor计算分页逻辑,生成带页码参数的链接,同时处理边界禁用状态:

<div class="pagination-container mt-4">
    <nav aria-label="分页导航">
        <ul class="pagination">
            <!-- 上一页按钮 -->
            <li class="page-item @(Model.CurrentPage == 1 ? "disabled" : "")">
                <a class="page-link" 
                   href="@Url.Action("Index", new { page = Model.CurrentPage - 1 })"
                   @(Model.CurrentPage == 1 ? "tabindex='-1' aria-disabled='true'" : "")>
                    上一页
                </a>
            </li>

            <!-- 页码按钮:优化显示逻辑,避免总页数过多时按钮挤在一起 -->
            @{
                int startPage = Math.Max(1, Model.CurrentPage - 2);
                int endPage = Math.Min(Model.TotalPages, Model.CurrentPage + 2);
            }

            <!-- 显示首页 -->
            @if (startPage > 1)
            {
                <li class="page-item">
                    <a class="page-link" href="@Url.Action("Index", new { page = 1 })">1</a>
                </li>
                @if (startPage > 2)
                {
                    <li class="page-item disabled"><span class="page-link">...</span></li>
                }
            }

            <!-- 显示当前页前后的页码 -->
            @for (int i = startPage; i <= endPage; i++)
            {
                <li class="page-item @(i == Model.CurrentPage ? "active" : "")">
                    <a class="page-link" href="@Url.Action("Index", new { page = i })">
                        @i
                    </a>
                </li>
            }

            <!-- 显示尾页 -->
            @if (endPage < Model.TotalPages)
            {
                @if (endPage < Model.TotalPages - 1)
                {
                    <li class="page-item disabled"><span class="page-link">...</span></li>
                }
                <li class="page-item">
                    <a class="page-link" href="@Url.Action("Index", new { page = Model.TotalPages })">
                        @Model.TotalPages
                    </a>
                </li>
            }

            <!-- 下一页按钮 -->
            <li class="page-item @(Model.CurrentPage == Model.TotalPages ? "disabled" : "")">
                <a class="page-link" 
                   href="@Url.Action("Index", new { page = Model.CurrentPage + 1 })"
                   @(Model.CurrentPage == Model.TotalPages ? "tabindex='-1' aria-disabled='true'" : "")>
                    下一页
                </a>
            </li>
        </ul>
    </nav>
</div>

4. 关键注意事项

  • 视图里的Url.Action只是生成跳转链接,并没有主动调用控制器方法,完全符合你的要求;
  • 必须确保控制器里的查询先排序再分页,否则EF6的Skip会返回不稳定的结果;
  • 可以根据需求调整PageSize,或者把它做成可配置的参数(比如从配置文件读取);
  • 如果需要带其他查询参数(比如搜索条件),只需要在Url.Action的匿名对象里添加对应参数即可,比如new { page = i, keyword = ViewBag.SearchKeyword }。

内容的提问来源于stack exchange,提问作者Rawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:15:08