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

MVC Razor WebGrid表头排序丢失类别筛选状态的解决问询

解决MVC Razor WebGrid排序丢失筛选状态的问题

问题根源

WebGrid默认生成的表头排序链接仅携带sort(排序字段)和sortdir(排序方向)参数,不会自动附加当前的筛选条件(比如类别ID)。点击排序时控制器无法获取之前的筛选参数,因此返回全部数据,导致筛选状态丢失。

核心解决方案

让WebGrid的排序链接自动带上当前的筛选参数,同时控制器方法支持接收筛选+排序参数,组合执行数据查询。以下是完整实现代码:


1. 模型定义

// 产品实体模型
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
}

// 筛选+列表视图模型
public class ProductFilterViewModel
{
    public int? SelectedCategoryId { get; set; }
    public List<SelectListItem> Categories { get; set; }
    public WebGrid Grid { get; set; }
    public IEnumerable<Product> Products { get; set; }
}

2. 控制器实现

public ActionResult Index(int? selectedCategoryId, string sortColumn = "Name", string sortDirection = "ASC")
{
    // 构造类别下拉选项(实际项目从数据库读取)
    var categories = new List<SelectListItem>
    {
        new SelectListItem { Value = "", Text = "全部类别" },
        new SelectListItem { Value = "1", Text = "电子产品" },
        new SelectListItem { Value = "2", Text = "家居用品" },
        new SelectListItem { Value = "3", Text = "服装" }
    };

    // 获取模拟产品数据(实际从数据库查询)
    var products = GetMockProducts();

    // 应用类别筛选
    if (selectedCategoryId.HasValue)
    {
        products = products.Where(p => p.CategoryId == selectedCategoryId.Value);
    }

    // 应用排序逻辑
    var property = typeof(Product).GetProperty(sortColumn);
    products = sortDirection.Equals("ASC", StringComparison.OrdinalIgnoreCase)
        ? products.OrderBy(p => property.GetValue(p, null))
        : products.OrderByDescending(p => property.GetValue(p, null));

    // 初始化WebGrid,指定排序参数
    var grid = new WebGrid(
        source: products,
        defaultSort: sortColumn,
        sortDirectionFieldName: "sortDirection",
        canSort: true
    );

    // 构建视图模型
    var viewModel = new ProductFilterViewModel
    {
        SelectedCategoryId = selectedCategoryId,
        Categories = categories,
        Grid = grid,
        Products = products
    };

    return View(viewModel);
}

// 模拟数据库产品数据
private List<Product> GetMockProducts()
{
    return new List<Product>
    {
        new Product { Id = 1, Name = "手机", Price = 2999, CategoryId = 1, CategoryName = "电子产品" },
        new Product { Id = 2, Name = "电视", Price = 5999, CategoryId = 1, CategoryName = "电子产品" },
        new Product { Id = 3, Name = "沙发", Price = 3999, CategoryId = 2, CategoryName = "家居用品" },
        new Product { Id = 4, Name = "床单", Price = 299, CategoryId = 2, CategoryName = "家居用品" },
        new Product { Id = 5, Name = "T恤", Price = 99, CategoryId = 3, CategoryName = "服装" },
        new Product { Id = 6, Name = "牛仔裤", Price = 199, CategoryId = 3, CategoryName = "服装" }
    };
}

3. Razor页面(Index.cshtml)

关键是修改WebGrid生成的排序链接,追加当前筛选参数:

@model ProductFilterViewModel

@{
    ViewBag.Title = "产品列表";
    var selectedCategoryId = Model.SelectedCategoryId ?? 0;
}

<h2>产品列表</h2>

<!-- 类别筛选区域 -->
<div class="filter-area mb-3">
    <label class="me-2">选择类别:</label>
    @Html.DropDownListFor(m => m.SelectedCategoryId, Model.Categories, new { @id = "categoryFilter", @class = "form-control d-inline-block w-auto" })
    <button id="filterBtn" class="btn btn-primary ms-2">筛选</button>
</div>

<!-- WebGrid容器 -->
<div id="grid-container" class="grid-container">
    @{
        var grid = Model.Grid;
        grid.Columns(
            grid.Column("Id", "ID", canSort: true),
            grid.Column("Name", "产品名称", canSort: true),
            grid.Column("Price", "价格", canSort: true),
            grid.Column("CategoryName", "类别")
        );

        // 生成WebGrid原始HTML
        string gridHtml = grid.GetHtml(
            tableStyle: "table table-striped table-bordered",
            headerStyle: "table-dark",
            sortColumnHeaderStyle: "sortable-column",
            sortDirectionHeaderStyle: "sort-direction",
            mode: WebGridPagerModes.All,
            columns: grid.Columns
        ).ToString();

        // 给排序链接追加类别筛选参数
        if (selectedCategoryId > 0)
        {
            gridHtml = gridHtml.Replace("?", $"?selectedCategoryId={selectedCategoryId}&");
            gridHtml = gridHtml.Replace("&sort=", $"&selectedCategoryId={selectedCategoryId}&sort=");
        }

        // 输出修改后的WebGrid
        @Html.Raw(gridHtml)
    }
</div>

<!-- 筛选交互脚本 -->
<script src="~/Scripts/jquery-3.6.0.min.js"></script>
<script>
    $(document).ready(function () {
        // 筛选按钮点击事件
        $("#filterBtn").click(function () {
            var categoryId = $("#categoryFilter").val();
            window.location.href = '@Url.Action("Index")' + (categoryId ? `?selectedCategoryId=${categoryId}` : "");
        });

        // 下拉框回车触发筛选
        $("#categoryFilter").keypress(function (e) {
            if (e.which === 13) $("#filterBtn").click();
        });
    });
</script>

4. 优化方案:AJAX无刷新排序(可选)

如果想要更流畅的体验,可改用WebGrid的AJAX模式,避免页面刷新:

  1. 修改WebGrid初始化代码,添加AJAX配置:
var grid = new WebGrid(
    source: products,
    defaultSort: sortColumn,
    sortDirectionFieldName: "sortDirection",
    canSort: true,
    ajaxUpdateContainerId: "grid-container" // 指定AJAX更新的容器ID
);
  1. 替换页面脚本,拦截排序链接的点击事件,追加筛选参数后发起AJAX请求:
$(document).ready(function () {
    // 筛选按钮逻辑不变
    $("#filterBtn").click(function () {
        var categoryId = $("#categoryFilter").val();
        $("#grid-container").load('@Url.Action("Index")' + (categoryId ? `?selectedCategoryId=${categoryId}` : ""));
    });

    // 拦截排序链接点击,追加筛选参数
    $(document).on("click", ".sortable-column a", function (e) {
        e.preventDefault();
        var url = $(this).attr("href");
        var categoryId = $("#categoryFilter").val();
        if (categoryId) {
            url += (url.indexOf("?") > -1 ? "&" : "?") + `selectedCategoryId=${categoryId}`;
        }
        $("#grid-container").load(url);
    });
});

问题场景说明

  • 问题状态:选择“电子产品”筛选后,点击“价格”表头排序,页面跳转到全部产品的排序结果,丢失筛选状态。
  • 修复后状态:筛选后表头排序链接自动携带selectedCategoryId=1参数,点击排序时仅对当前类别下的产品进行排序,维持筛选状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:55:28