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

ASP.NET Core MVC中带筛选参数保留的分页实现问题

解决ASP.NET Core MVC分页时保留多参数筛选的问题

你的第二个方案出错的核心原因是:asp-route-*标签助手无法直接正确绑定List<string>类型的参数,它会将集合对象直接转为字符串(比如System.Collections.Generic.List1[System.String]),而不是生成多个同名的查询参数(如selectedCountries=USA&selectedCountries=UK`)。

下面提供两种可靠的实现方式:

方法1:使用asp-all-route-data传递所有参数

这种方式可以自动处理集合类型,无需手动逐个添加参数:

步骤1:在ViewModel中构建路由数据字典

在MovieViewModel中添加属性,将筛选参数和分页参数打包成RouteValueDictionary:

public record MovieViewModel
{
    // 原有属性...
    public List<Movie> docs { get; set; }
    public int total { get; set; }
    public int limit { get; set; }
    public int page { get; set; }
    public int pages { get; set; }
    public MovieFilters movieFilters { get; set; }

    // 用于传递路由参数的字典
    public RouteValueDictionary RouteData
    {
        get
        {
            var routeData = new RouteValueDictionary();
            // 基础分页参数
            routeData["page"] = page;
            
            // 遍历添加筛选集合参数
            if (movieFilters?.Genres?.Any() == true)
            {
                foreach (var genre in movieFilters.Genres)
                    routeData.Add("selectedGenres", genre);
            }
            if (movieFilters?.Countries?.Any() == true)
            {
                foreach (var country in movieFilters.Countries)
                    routeData.Add("selectedCountries", country);
            }
            if (movieFilters?.Years?.Any() == true)
            {
                foreach (var year in movieFilters.Years)
                    routeData.Add("selectedYears", year);
            }
            return routeData;
        }
    }
}

步骤2:在视图中使用标签助手

分页链接修改为:

<li class="page-item @(Model.page >= Model.pages ? "disabled" : "")">
    <a 
        class="page-link" 
        asp-controller="Home" 
        asp-action="SearchByFilters"
        asp-all-route-data="@Model.RouteData"
        asp-route-page="@(Model.page + 1)">
        Next
    </a>
</li>

注:asp-route-page会覆盖字典中的page值,确保传递下一页的页码。

方法2:手动构建查询字符串

如果不想修改ViewModel,可直接在视图中遍历筛选集合拼接参数:

@{
    var queryParts = new List<string>();
    // 添加下一页参数
    queryParts.Add($"page={Model.page + 1}");
    
    // 处理流派筛选
    if (Model.MovieFilters?.Genres?.Any() == true)
    {
        queryParts.AddRange(Model.MovieFilters.Genres
            .Select(g => $"selectedGenres={Uri.EscapeDataString(g)}"));
    }
    // 处理国家筛选
    if (Model.MovieFilters?.Countries?.Any() == true)
    {
        queryParts.AddRange(Model.MovieFilters.Countries
            .Select(c => $"selectedCountries={Uri.EscapeDataString(c)}"));
    }
    // 处理年份筛选
    if (Model.MovieFilters?.Years?.Any() == true)
    {
        queryParts.AddRange(Model.MovieFilters.Years
            .Select(y => $"selectedYears={Uri.EscapeDataString(y)}"));
    }
    
    var nextPageUrl = $"/Home/SearchByFilters?{string.Join("&", queryParts)}";
}

<li class="page-item @(Model.page >= Model.pages ? "disabled" : "")">
    <a class="page-link" href="@nextPageUrl">Next</a>
</li>

使用Uri.EscapeDataString可避免特殊字符导致的URL编码问题,保证参数传递准确。

额外优化建议

  • 将分页逻辑封装为局部视图,减少重复代码;
  • 控制器方法可改用[FromQuery]直接绑定筛选对象,简化参数列表:
public async Task<IActionResult> SearchByFilters([FromQuery] MovieFilters filters, int page = 1)
{
    var dataFromApi = await _kinopoiskApiService.GetMoviesByFilter(filters, page);
    // 后续逻辑不变
}
  • 添加参数校验,比如限制page不能小于1,避免无效请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:48:20