ASP.NET Core中基于StudentCourseViewModel实现多条件搜索栏的步骤与代码
ASP.NET Core EF 实现带多条件搜索的学生列表
一、模型调整
扩展现有视图模型,新增搜索参数模型并更新展示用视图模型:
1. 搜索参数模型
用于接收前端提交的搜索条件:
public class StudentSearchParams { public string? StudentName { get; set; } public string? MotherName { get; set; } public string? CourseName { get; set; } public decimal? MinFee { get; set; } public decimal? MaxFee { get; set; } public int? MinAge { get; set; } public int? MaxAge { get; set; } }
2. 更新学生展示视图模型
确保包含关联课程名称等所有展示字段:
public class StudentCourseViewModel { public int StudentRollNo { get; set; } public string Name { get; set; } = string.Empty; public string MotherName { get; set; } = string.Empty; public string Class { get; set; } = string.Empty; public int Age { get; set; } public decimal FeePaid { get; set; } public string CourseName { get; set; } = string.Empty; public bool IsActive { get; set; } }
二、异步控制器方法
在StudentController中实现页面初始化和异步搜索逻辑:
using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using YourNamespace.Data; public class StudentController : Controller { private readonly AppDbContext _context; public StudentController(AppDbContext context) { _context = context; } // 加载初始学生列表页面 public async Task<IActionResult> Index() { var students = await GetFilteredStudentsAsync(new StudentSearchParams()); return View(students); } // 异步搜索接口,返回列表部分视图 [HttpPost] public async Task<IActionResult> SearchStudents(StudentSearchParams searchParams) { var students = await GetFilteredStudentsAsync(searchParams); return PartialView("_StudentList", students); } // 封装过滤逻辑的私有方法 private async Task<List<StudentCourseViewModel>> GetFilteredStudentsAsync(StudentSearchParams searchParams) { var query = from s in _context.Students join c in _context.Courses on s.CourseID equals c.courseid where s.IsActive && c.IsActive select new StudentCourseViewModel { StudentRollNo = s.StudentRollNo, Name = s.Name, MotherName = s.MotherName, Class = s.Class, Age = s.Age, FeePaid = s.FeePaid, CourseName = c.CourseName, IsActive = s.IsActive }; // 应用各搜索条件 if (!string.IsNullOrEmpty(searchParams.StudentName)) query = query.Where(s => s.Name.Contains(searchParams.StudentName)); if (!string.IsNullOrEmpty(searchParams.MotherName)) query = query.Where(s => s.MotherName.Contains(searchParams.MotherName)); if (!string.IsNullOrEmpty(searchParams.CourseName)) query = query.Where(s => s.CourseName.Contains(searchParams.CourseName)); if (searchParams.MinFee.HasValue) query = query.Where(s => s.FeePaid >= searchParams.MinFee.Value); if (searchParams.MaxFee.HasValue) query = query.Where(s => s.FeePaid <= searchParams.MaxFee.Value); if (searchParams.MinAge.HasValue) query = query.Where(s => s.Age >= searchParams.MinAge.Value); if (searchParams.MaxAge.HasValue) query = query.Where(s => s.Age <= searchParams.MaxAge.Value); return await query.ToListAsync(); } }
三、视图实现
1. 主视图(Index.cshtml)
包含搜索栏和列表容器,通过AJAX异步更新列表:
@model List<StudentCourseViewModel> @{ ViewData["Title"] = "学生列表"; } <h1>学生列表</h1> <!-- 搜索表单 --> <div class="card mb-3"> <div class="card-body"> <form id="searchForm"> <div class="row g-3"> <div class="col-md-2"> <label class="form-label">学生姓名</label> <input type="text" class="form-control" name="StudentName" placeholder="输入姓名"> </div> <div class="col-md-2"> <label class="form-label">母亲姓名</label> <input type="text" class="form-control" name="MotherName" placeholder="输入母亲姓名"> </div> <div class="col-md-2"> <label class="form-label">课程名称</label> <input type="text" class="form-control" name="CourseName" placeholder="输入课程名"> </div> <div class="col-md-2"> <label class="form-label">最低费用</label> <input type="number" step="0.01" class="form-control" name="MinFee" placeholder="最低费用"> </div> <div class="col-md-2"> <label class="form-label">最高费用</label> <input type="number" step="0.01" class="form-control" name="MaxFee" placeholder="最高费用"> </div> <div class="col-md-2"> <label class="form-label">年龄范围</label> <div class="d-flex gap-2"> <input type="number" class="form-control" name="MinAge" placeholder="最小"> <span>-</span> <input type="number" class="form-control" name="MaxAge" placeholder="最大"> </div> </div> <div class="col-12"> <button type="button" id="searchBtn" class="btn btn-primary">搜索</button> <button type="button" id="resetBtn" class="btn btn-secondary">重置</button> </div> </div> </form> </div> </div> <!-- 学生列表容器 --> <div id="studentListContainer"> @await Html.PartialAsync("_StudentList", Model) </div> <script> // 搜索按钮事件 document.getElementById('searchBtn').addEventListener('click', performSearch); // 重置按钮事件 document.getElementById('resetBtn').addEventListener('click', function () { document.getElementById('searchForm').reset(); performSearch(); }); // 异步提交搜索请求 function performSearch() { const formData = new FormData(document.getElementById('searchForm')); fetch('/Student/SearchStudents', { method: 'POST', headers: { 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value, 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams(formData) }) .then(response => response.text()) .then(html => { document.getElementById('studentListContainer').innerHTML = html; }) .catch(error => console.error('搜索失败:', error)); } </script>
2. 学生列表部分视图(_StudentList.cshtml)
负责渲染学生表格,支持复用:
@model List<StudentCourseViewModel> <table class="table table-striped"> <thead> <tr> <th>学号</th> <th>学生姓名</th> <th>母亲姓名</th> <th>班级</th> <th>年龄</th> <th>已缴费用</th> <th>课程名称</th> <th>状态</th> </tr> </thead> <tbody> @if (Model.Any()) { foreach (var student in Model) { <tr> <td>@student.StudentRollNo</td> <td>@student.Name</td> <td>@student.MotherName</td> <td>@student.Class</td> <td>@student.Age</td> <td>@student.FeePaid.ToString("C")</td> <td>@student.CourseName</td> <td>@(student.IsActive ? "激活" : "禁用")</td> </tr> } } else { <tr> <td colspan="8" class="text-center">没有找到匹配的学生</td> </tr> } </tbody> </table>
四、注意事项
- 确保
AppDbContext中正确配置实体关联:public DbSet<Student> Students { get; set; } public DbSet<Course> Courses { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Student>() .HasOne<Course>() .WithMany() .HasForeignKey(s => s.CourseID); } - 如需分页,可在
StudentSearchParams中添加PageIndex和PageSize,并在过滤逻辑中使用Skip()和Take()实现分页。 - 代码中已包含防伪令牌处理,避免CSRF攻击。
内容的提问来源于stack exchange,提问作者CuriousLife
相关产品推荐
相关产品推荐

