ASP.NET 6中使用Fetch API实现车辆列表无刷新筛选
实现ASP.NET 6 MVC多条件无刷新车辆筛选
1. 改造控制器方法,支持多参数筛选与AJAX请求
修改你的CarsController的Index方法,接收所有筛选参数并构建动态LINQ查询,同时区分AJAX请求返回局部视图:
using Microsoft.EntityFrameworkCore; using YourProjectNamespace.Models; public class CarsController : Controller { private readonly AppDbContext _context; public CarsController(AppDbContext context) { _context = context; } public async Task<IActionResult> Index( List<string>? brands, string? model, int? minYear, int? maxYear, decimal? minPrice, decimal? maxPrice) { var query = _context.Cars.AsQueryable(); // 品牌复选框筛选 if (brands != null && brands.Any()) { query = query.Where(c => brands.Contains(c.Brand)); } // 型号模糊筛选 if (!string.IsNullOrWhiteSpace(model)) { query = query.Where(c => c.Model.Contains(model)); } // 年份范围筛选 if (minYear.HasValue) { query = query.Where(c => c.Year >= minYear.Value); } if (maxYear.HasValue) { query = query.Where(c => c.Year <= maxYear.Value); } // 价格范围筛选 if (minPrice.HasValue) { query = query.Where(c => c.Price >= minPrice.Value); } if (maxPrice.HasValue) { query = query.Where(c => c.Price <= maxPrice.Value); } var cars = await query.ToListAsync(); // 判断是否为AJAX请求,返回局部视图 if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") { return PartialView("_CarPartial", cars); } // 首次加载返回完整视图 return View(cars); } }
2. 前端筛选表单与Fetch API实现
在Index.cshtml中构建筛选表单,并编写JS监听筛选变化,通过Fetch请求更新车辆列表:
<!-- 筛选区域 --> <div class="filter-panel"> <!-- 品牌复选组 --> <div class="filter-group"> <h5>品牌</h5> <label><input type="checkbox" name="brands" value="宝马"> 宝马</label> <label><input type="checkbox" name="brands" value="奔驰"> 奔驰</label> <label><input type="checkbox" name="brands" value="奥迪"> 奥迪</label> </div> <!-- 型号输入框 --> <div class="filter-group"> <h5>型号</h5> <input type="text" id="model-input" placeholder="输入型号关键词"> </div> <!-- 年份范围 --> <div class="filter-group"> <h5>年份范围</h5> <input type="number" id="min-year" placeholder="最小年份" min="1990" max="@DateTime.Now.Year"> <input type="number" id="max-year" placeholder="最大年份" min="1990" max="@DateTime.Now.Year"> </div> <!-- 价格范围 --> <div class="filter-group"> <h5>价格范围</h5> <input type="number" id="min-price" placeholder="最低价格" min="0"> <input type="number" id="max-price" placeholder="最高价格" min="0"> </div> <button id="apply-filters">应用筛选</button> <button id="reset-filters">重置筛选</button> </div> <!-- 车辆列表容器(用于替换局部视图) --> <div id="car-list-container"> @await Html.PartialAsync("_CarPartial", Model) </div> <script> // 绑定筛选触发事件 document.getElementById('apply-filters').addEventListener('click', applyFilters); document.getElementById('reset-filters').addEventListener('click', resetFilters); // 实时监听输入变化(可选) document.querySelectorAll('.filter-panel input').forEach(input => { input.addEventListener('change', applyFilters); }); async function applyFilters() { const formData = new FormData(); // 收集选中的品牌 document.querySelectorAll('input[name="brands"]:checked').forEach(cb => { formData.append('brands', cb.value); }); // 收集其他筛选值 formData.append('model', document.getElementById('model-input').value.trim()); formData.append('minYear', document.getElementById('min-year').value || ''); formData.append('maxYear', document.getElementById('max-year').value || ''); formData.append('minPrice', document.getElementById('min-price').value || ''); formData.append('maxPrice', document.getElementById('max-price').value || ''); try { // 构建查询字符串(GET请求参数拼接) const searchParams = new URLSearchParams(formData); const response = await fetch(`/Cars/Index?${searchParams}`, { method: 'GET', headers: { 'X-Requested-With': 'XMLHttpRequest', // 标记AJAX请求 'Accept': 'text/html' } }); if (!response.ok) throw new Error('筛选请求失败'); const html = await response.text(); document.getElementById('car-list-container').innerHTML = html; } catch (err) { console.error('筛选出错:', err); } } function resetFilters() { // 清空所有筛选输入 document.querySelectorAll('.filter-panel input').forEach(input => { if (input.type === 'checkbox') input.checked = false; else input.value = ''; }); // 重新加载默认列表 applyFilters(); } </script>
3. 局部视图_CarPartial.cshtml适配
确保局部视图仅渲染车辆列表,无多余布局:
@model List<YourProjectNamespace.Models.Car> <div class="car-grid"> @foreach (var car in Model) { <div class="car-card"> <h3>@car.Brand @car.Model</h3> <p>年份: @car.Year</p> <p>价格: @car.Price.ToString("C")</p> <!-- 其他车辆信息字段 --> </div> } @if (!Model.Any()) { <p class="no-results">未找到符合条件的车辆</p> } </div>
关键注意事项
- 参数绑定:ASP.NET MVC会自动将URL中的
brands=宝马&brands=奔驰这类参数绑定到List<string> brands参数 - 空值处理:控制器中对所有参数做空值判断,避免LINQ查询抛出异常
- 性能优化:数据量大时需添加分页逻辑,在控制器中接收
page和pageSize参数并修改LINQ查询 - 兼容性:
X-Requested-With头是识别AJAX请求的标准方式,确保控制器能正确区分请求类型
内容的提问来源于stack exchange,提问作者Antoine Lardant
相关产品推荐
相关产品推荐

