ASP.NET Core 6 MVC:回发后保留DropDownList选中值
解决ASP.NET Core 6 MVC DropDownList回发后选中值重置的问题
问题核心是Post请求重新生成SelectList时未指定选中项,导致下拉框无法保留用户之前的选择。以下是针对你现有代码的修复方案:
修复步骤(基于ViewBag的快速修改)
修改StudentsController中的[HttpPost] Index方法,在创建SelectList时传入用户选中的分组ID作为默认选中值:
[HttpPost] public async Task<IActionResult> Index(string groups) { // 处理空值,避免转换出错,默认选中GroupId=1 int Id = string.IsNullOrEmpty(groups) ? 1 : Convert.ToInt32(groups); // 重点:在SelectList构造中加入第四个参数(选中值) ViewBag.ListOfGroups = new SelectList( _context.Groups.OrderBy(k => k.Level).ThenBy(k => k.ShortName), "GroupId", "ShortName", Id); // 传入选中的Id var applicationDbContext = _context.Students .Where(k => k.Group.GroupId == Id) .Include(s => s.Group) .OrderBy(k => k.Group.Level) .ThenBy(k => k.Group.ShortName) .ThenBy(k => k.Number); return View(await applicationDbContext.ToListAsync()); }
补充:优化HttpGet方法的默认选中(可选)
如果希望首次加载页面时默认选中GroupId=1的选项,也可以在HttpGet的Index方法中加入选中值:
public async Task<IActionResult> Index() { int defaultGroupId = 1; ViewBag.ListOfGroups = new SelectList( _context.Groups.OrderBy(k => k.Seviye).ThenBy(k => k.ShortName), "GroupId", "ShortName", defaultGroupId); var applicationDbContext = _context.Students .Where(k => k.Group.GroupId == defaultGroupId) .Include(s => s.Group) .OrderBy(k => k.Group.Level) .ThenBy(k => k.Group.ShortName) .ThenBy(k => k.Number); return View(await applicationDbContext.ToListAsync()); }
更规范的强类型视图模型方案(推荐)
长期来看,使用强类型ViewModel更符合ASP.NET Core的设计原则,避免ViewBag的弱类型问题:
- 创建ViewModel类:
public class StudentListViewModel { public int SelectedGroupId { get; set; } public IEnumerable<SelectListItem> GroupOptions { get; set; } public IEnumerable<Student> Students { get; set; } }
- 修改控制器方法:
public async Task<IActionResult> Index() { var viewModel = new StudentListViewModel { SelectedGroupId = 1, GroupOptions = new SelectList( _context.Groups.OrderBy(k => k.Seviye).ThenBy(k => k.ShortName), "GroupId", "ShortName"), Students = await _context.Students .Where(k => k.Group.GroupId == 1) .Include(s => s.Group) .OrderBy(k => k.Group.Level) .ThenBy(k => k.Group.ShortName) .ThenBy(k => k.Number) .ToListAsync() }; return View(viewModel); } [HttpPost] public async Task<IActionResult> Index(StudentListViewModel viewModel) { viewModel.GroupOptions = new SelectList( _context.Groups.OrderBy(k => k.Level).ThenBy(k => k.ShortName), "GroupId", "ShortName", viewModel.SelectedGroupId); viewModel.Students = await _context.Students .Where(k => k.Group.GroupId == viewModel.SelectedGroupId) .Include(s => s.Group) .OrderBy(k => k.Group.Level) .ThenBy(k => k.Group.ShortName) .ThenBy(k => k.Number) .ToListAsync(); return View(viewModel); }
- 修改视图代码:
@model Proje.Models.StudentListViewModel <form asp-action="Index" method="post" > @Html.DropDownListFor(m => m.SelectedGroupId, Model.GroupOptions, "Select...", new {@class="form-control"}) <button type="submit" class="btn btn-sm btn-danger">List</button> </form> <!-- 学生列表展示代码 --> @foreach(var student in Model.Students) { <!-- 输出学生信息 --> }
内容的提问来源于stack exchange,提问作者Zafer Andaç Özer
相关产品推荐
相关产品推荐

