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

ASP.NET MVC视图中如何通过下拉框选项变更过滤C# DataTable?

两种方案实现MVC下拉框过滤DataTable数据

我来给你梳理两种实用的实现思路,分别对应服务器端刷新过滤和客户端无刷新过滤,你可以根据项目场景选最合适的方式:


一、前置准备:ViewModel与Controller基础代码

首先我们需要定义ViewModel来传递下拉框选项、原始DataTable(或JSON格式数据),以及当前选中的过滤值:

1. ViewModel定义

public class DataFilterViewModel
{
    // 下拉框的选项列表
    public List<SelectListItem> FilterOptions { get; set; }
    // 原始DataTable(服务器端过滤用)
    public DataTable RawDataTable { get; set; }
    // 转成JSON的原始数据(客户端过滤用)
    public string RawDataJson { get; set; }
    // 当前选中的过滤值
    public string SelectedFilterValue { get; set; }
}

2. Controller初始化数据

public ActionResult Index()
{
    var viewModel = new DataFilterViewModel();
    
    // 初始化下拉框选项(比如包含ABCD、EFGH等选项)
    viewModel.FilterOptions = new List<SelectListItem>
    {
        new SelectListItem { Text = "筛选ABCD", Value = "ABCD" },
        new SelectListItem { Text = "筛选EFGH", Value = "EFGH" },
        new SelectListItem { Text = "显示全部", Value = "" }
    };
    
    // 模拟从数据库/业务层获取原始DataTable
    var originalTable = GetSampleDataTable();
    
    // 服务器端过滤:直接传递DataTable
    viewModel.RawDataTable = originalTable;
    
    // 客户端过滤:将DataTable转成JSON(需要安装Newtonsoft.Json NuGet包)
    viewModel.RawDataJson = JsonConvert.SerializeObject(originalTable);
    
    return View(viewModel);
}

// 模拟获取带过滤列的DataTable
private DataTable GetSampleDataTable()
{
    var table = new DataTable();
    table.Columns.Add("UniqueKey", typeof(string));
    table.Columns.Add("FilterColumn", typeof(string)); // 用于过滤的列
    table.Columns.Add("CorrespondingValue", typeof(string)); // 对应值列
    
    // 示例数据
    table.Rows.Add("KEY001", "ABCD", "ABCD对应值1");
    table.Rows.Add("KEY002", "ABCD", "ABCD对应值2");
    table.Rows.Add("KEY003", "EFGH", "EFGH对应值1");
    table.Rows.Add("KEY004", "ABCD", "ABCD对应值3");
    return table;
}

二、方案1:服务器端刷新过滤(简单易上手)

这种方式通过提交表单触发Controller重新过滤DataTable,适合数据量较小、对无刷新体验要求不高的场景。

View代码(Index.cshtml)

@model DataFilterViewModel

<!-- 下拉框表单,选择后自动提交 -->
@using (Html.BeginForm("Index", "YourControllerName", FormMethod.Post))
{
    @Html.DropDownListFor(m => m.SelectedFilterValue, Model.FilterOptions, 
                         new { onchange = "this.form.submit();", @class = "form-control" })
}

<!-- 渲染过滤后的DataTable -->
<table class="table table-bordered mt-3">
    <thead>
        <tr>
            @foreach (DataColumn col in Model.RawDataTable.Columns)
            {
                <th>@col.ColumnName</th>
            }
        </tr>
    </thead>
    <tbody>
        @foreach (DataRow row in Model.RawDataTable.Rows)
        {
            <tr>
                @foreach (var cellValue in row.ItemArray)
                {
                    <td>@cellValue.ToString()</td>
                }
            </tr>
        }
    </tbody>
</table>

补充Controller的Post方法

[HttpPost]
public ActionResult Index(DataFilterViewModel model)
{
    // 重新初始化下拉框选项
    model.FilterOptions = new List<SelectListItem>
    {
        new SelectListItem { Text = "筛选ABCD", Value = "ABCD" },
        new SelectListItem { Text = "筛选EFGH", Value = "EFGH" },
        new SelectListItem { Text = "显示全部", Value = "" }
    };
    
    var originalTable = GetSampleDataTable();
    
    // 根据选中值过滤DataTable
    if (!string.IsNullOrEmpty(model.SelectedFilterValue))
    {
        // 这里的"FilterColumn"要和你DataTable中的过滤列名一致
        model.RawDataTable = originalTable.AsEnumerable()
            .Where(row => row.Field<string>("FilterColumn") == model.SelectedFilterValue)
            .CopyToDataTable();
    }
    else
    {
        model.RawDataTable = originalTable;
    }
    
    return View(model);
}

三、方案2:客户端无刷新过滤(体验更好)

这种方式将原始数据转成JSON传给前端,用JavaScript实现下拉框变更时的即时过滤和表格重渲染,适合对用户体验要求高的场景。

View代码(Index.cshtml)

@model DataFilterViewModel

<!-- 下拉框,绑定JS变更事件 -->
@Html.DropDownList("FilterDropdown", Model.FilterOptions, "请选择筛选条件", 
                   new { id = "filterDropdown", @class = "form-control" })

<!-- 用于渲染数据的表格容器 -->
<table class="table table-bordered mt-3" id="dataTable">
    <thead></thead>
    <tbody></tbody>
</table>

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
    // 从后端获取的原始JSON数据
    const originalData = @Html.Raw(Model.RawDataJson);
    
    // 渲染表格的核心函数
    function renderFilteredTable(filterValue) {
        const table = $('#dataTable');
        const thead = table.find('thead');
        const tbody = table.find('tbody');
        
        // 清空现有内容
        thead.empty();
        tbody.empty();
        
        // 渲染表头(如果有数据)
        if (originalData.length > 0) {
            const headerRow = $('<tr>');
            Object.keys(originalData[0]).forEach(colName => {
                headerRow.append($('<th>').text(colName));
            });
            thead.append(headerRow);
            
            // 过滤数据:匹配FilterColumn的值
            let filteredData = originalData;
            if (filterValue) {
                filteredData = originalData.filter(row => row.FilterColumn === filterValue);
            }
            
            // 渲染表体
            filteredData.forEach(row => {
                const dataRow = $('<tr>');
                Object.values(row).forEach(cellValue => {
                    dataRow.append($('<td>').text(cellValue));
                });
                tbody.append(dataRow);
            });
        }
    }
    
    // 页面加载时初始化表格
    $(document).ready(function() {
        renderFilteredTable(""); // 默认显示全部数据
        
        // 下拉框变更时触发过滤
        $('#filterDropdown').change(function() {
            const selectedValue = $(this).val();
            renderFilteredTable(selectedValue);
        });
    });
</script>

注意事项

  1. 如果你用客户端过滤,要注意敏感数据不能用这种方式,因为JSON数据会暴露在前端源码中。
  2. 数据量过大时不建议用客户端过滤,会增加页面加载时间和前端内存占用,此时优先选服务器端方案。
  3. 代码中的FilterColumn要替换成你实际DataTable中用于过滤的列名(比如用户提到的对应ABCD的列)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:58:15