ASP.NET中Post请求间如何保留下拉选择列表状态?
解决ASP.NET验证失败后下拉列表丢失数据的简便方案
针对你遇到的验证失败后下拉列表选项丢失的问题,以下几种简便方案适合内网站点场景:
1. 封装获取选项列表的复用方法
把获取产品下拉选项的逻辑封装成私有方法,在GET请求和POST验证失败时统一调用,代码简洁且易维护:
// 控制器内封装复用方法 private IEnumerable<SelectListItem> GetProductSelectList() { return _dbContext.Products .Select(p => new SelectListItem { Value = p.Id.ToString(), Text = p.ProductName }) .ToList(); } // GET请求初始化页面 public IActionResult ProductManage() { var vm = new ProductManageViewModel { ProductSelectListItems = GetProductSelectList() }; return View(vm); } // POST提交验证失败时重新赋值选项 [HttpPost] public IActionResult ProductManage(ProductManageViewModel model) { if (!ModelState.IsValid) { // 复用封装方法获取选项,无需重复写查询逻辑 model.ProductSelectListItems = GetProductSelectList(); return View(model); } // 验证通过后的业务逻辑 _dbContext.SaveChanges(); return RedirectToAction("Index"); }
2. 用隐藏字段序列化保存选项列表
既然内网站点不担心性能,可将选项序列化为JSON字符串存在隐藏字段,POST回传后反序列化恢复:
视图代码:
<select asp-for="ProductID" asp-items="@Model.ProductSelectListItems"></select> <!-- 隐藏字段保存序列化后的选项列表 --> <input type="hidden" name="SerializedProductOptions" value='@System.Text.Json.JsonSerializer.Serialize(Model.ProductSelectListItems)' />
控制器代码:
[HttpPost] public IActionResult ProductManage(ProductManageViewModel model, string SerializedProductOptions) { if (!ModelState.IsValid) { // 反序列化恢复选项列表 model.ProductSelectListItems = System.Text.Json.JsonSerializer.Deserialize<IEnumerable<SelectListItem>>(SerializedProductOptions); return View(model); } // 业务逻辑处理 return RedirectToAction("Index"); }
3. 利用ViewData暂存选项
将选项存入ViewData,在GET和POST验证失败时统一赋值,ViewModel无需携带选项列表属性:
控制器代码:
public IActionResult ProductManage() { ViewData["ProductOptions"] = GetProductSelectList(); return View(new ProductManageViewModel()); } [HttpPost] public IActionResult ProductManage(ProductManageViewModel model) { if (!ModelState.IsValid) { ViewData["ProductOptions"] = GetProductSelectList(); return View(model); } // 业务逻辑 return RedirectToAction("Index"); }
视图代码:
<select asp-for="ProductID" asp-items="@ViewData["ProductOptions"] as IEnumerable<SelectListItem>"></select>
总结
如果觉得重新查库的代码不够简洁,封装复用方法是最稳妥且代码量最少的方案;如果完全不想重复查询数据库,序列化到隐藏字段是可行的选择,适合数据量小的内网站点。
内容的提问来源于stack exchange,提问作者John Hoge
相关产品推荐
相关产品推荐

