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

ASP MVC 5中点击分页链接提交表单以保留视图模型求助

解决ASP.NET MVC分页时丢失视图模型的问题

我明白你现在遇到的困扰——分页链接点击后视图模型直接丢失,导致之前的筛选条件和分页状态都没法保留。其实核心思路就是把分页操作转换成表单提交,这样所有筛选参数和分页信息就能一起传递给控制器了。下面我给你一步步演示具体实现方法:

问题回顾

你已经构建了CarViewModel,里面包含三类核心内容:

  • 存储数据的IEnumerable集合
  • 承载筛选条件的Filter类
  • 管理分页信息(当前页、页面大小、总页数等)的Pager类

目前筛选功能正常,但点击分页链接时,因为是默认的GET跳转,没法携带视图模型里的筛选参数,直接导致状态丢失。我们需要把分页链接的点击行为改成提交表单的操作。

实现步骤

1. 完善视图里的表单与分页链接

首先确保表单内包含所有需要保留的字段,尤其是分页相关的隐藏字段,同时给分页链接加上统一类名和页码标识:

@model TestFilteringAndPagination.ViewModels.CarViewModel 
@{ ViewBag.Title = "Home Page"; } 

@*搜索表单*@ 
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "frm" })) { 
    @* 分页相关隐藏字段 *@
    @Html.HiddenFor(m => Model.Pager.CurrentPage) 
    @Html.HiddenFor(m => Model.Pager.PageSize) 
    
    @* 筛选条件字段 *@
    <div class="filter-group">
        @Html.LabelFor(m => Model.Filter.Make)
        @Html.TextBoxFor(m => Model.Filter.Make)
        
        @Html.LabelFor(m => Model.Filter.Model)
        @Html.TextBoxFor(m => Model.Filter.Model)
        
        <!-- 其他筛选字段... -->
        <button type="submit" class="btn btn-primary">搜索</button>
    </div>

    @* 数据网格展示 *@
    <table class="table">
        <thead>
            <tr>
                <th>品牌</th>
                <th>型号</th>
                <!-- 其他列... -->
            </tr>
        </thead>
        <tbody>
            @foreach (var car in Model.Cars)
            {
                <tr>
                    <td>@car.Make</td>
                    <td>@car.Model</td>
                    <!-- 其他列内容... -->
                </tr>
            }
        </tbody>
    </table>
    
    @* 分页链接 *@
    <div class="pagination">
        @if (Model.Pager.CurrentPage > 1)
        {
            <a href="#" class="page-link" data-page="@(Model.Pager.CurrentPage - 1)">上一页</a>
        }
        @for (int i = 1; i <= Model.Pager.TotalPages; i++)
        {
            <a href="#" class="page-link @(i == Model.Pager.CurrentPage ? "active" : "")" data-page="@i">@i</a>
        }
        @if (Model.Pager.CurrentPage < Model.Pager.TotalPages)
        {
            <a href="#" class="page-link" data-page="@(Model.Pager.CurrentPage + 1)">下一页</a>
        }
    </div>
}

2. 添加JavaScript处理分页点击事件

在视图底部添加脚本,监听分页链接的点击事件,更新当前页码后提交表单:

@section Scripts {
    <script>
        $(document).ready(function() {
            // 给所有分页链接绑定点击事件
            $('.page-link').on('click', function(e) {
                e.preventDefault(); // 阻止默认的跳转行为
                
                // 获取目标页码
                const targetPage = $(this).data('page');
                
                // 更新表单里的CurrentPage隐藏字段
                const currentPageInput = $('#@Html.IdFor(m => m.Pager.CurrentPage)');
                currentPageInput.val(targetPage);
                
                // 提交表单,携带所有筛选和分页参数
                $('#frm').submit();
            });
        });
    </script>
}

3. 确保控制器正确接收并处理请求

控制器需要同时处理首次加载的GET请求,以及筛选/分页的POST请求,完整接收CarViewModel参数:

public class HomeController : Controller
{
    private readonly ICarService _carService; // 假设你有数据服务类

    public HomeController(ICarService carService)
    {
        _carService = carService;
    }

    // 首次加载页面,初始化视图模型
    [HttpGet]
    public ActionResult Index()
    {
        var viewModel = new CarViewModel
        {
            Pager = new Pager { CurrentPage = 1, PageSize = 10 },
            Filter = new Filter()
        };
        
        // 加载初始数据
        var allCars = _carService.GetAllCars();
        viewModel.Pager.TotalItems = allCars.Count();
        viewModel.Cars = allCars.Take(viewModel.Pager.PageSize).ToList();
        
        return View(viewModel);
    }

    // 处理筛选和分页提交
    [HttpPost]
    public ActionResult Index(CarViewModel viewModel)
    {
        if (ModelState.IsValid)
        {
            // 根据筛选条件获取数据
            var filteredCars = _carService.GetCarsByFilter(viewModel.Filter);
            
            // 更新分页信息与当前页数据
            viewModel.Pager.TotalItems = filteredCars.Count();
            viewModel.Cars = filteredCars
                .Skip((viewModel.Pager.CurrentPage - 1) * viewModel.Pager.PageSize)
                .Take(viewModel.Pager.PageSize)
                .ToList();
        }
        
        return View(viewModel);
    }
}

关键注意点

  • 所有筛选字段和分页字段必须包含在表单内,这样提交时才能完整传递给控制器
  • 用data-page属性存储目标页码,避免硬编码URL导致的维护问题
  • 点击分页链接时一定要阻止默认跳转,改用表单提交,确保视图模型的所有数据都被正确传递

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:14:18