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>
注意事项
- 如果你用客户端过滤,要注意敏感数据不能用这种方式,因为JSON数据会暴露在前端源码中。
- 数据量过大时不建议用客户端过滤,会增加页面加载时间和前端内存占用,此时优先选服务器端方案。
- 代码中的
FilterColumn要替换成你实际DataTable中用于过滤的列名(比如用户提到的对应ABCD的列)。
内容的提问来源于stack exchange,提问作者Bill Berlington
相关产品推荐
相关产品推荐

