提交Razor视图后Dropdown选中异常及InvalidOperationException报错咨询
解决HttpPost返回视图时DropDownListFor的InvalidOperationException错误
问题原因
你遇到的这个错误核心逻辑很清晰:HttpPost方法返回视图时,ViewModel里的LinkedServices下拉选项列表没有被重新初始化。
表单提交时,浏览器只会把用户选中的SelectedLinkedServiceId值回传给服务器,而下拉框的完整选项集合LinkedServices并不会被自动提交。当你直接返回vm时,这个LinkedServices属性是空的。此时Razor视图渲染DropDownListFor时,发现模型里的选项列表不存在,就会尝试去ViewData中查找与绑定属性同名(也就是SelectedLinkedServiceId)的集合,但ViewData里的这个值是你提交的int类型选中ID,完全不是IEnumerable<SelectListItem>类型,因此抛出了类型不匹配的异常。
解决方案
解决方法很直接:在HttpPost方法里,重新构建下拉框的选项列表并赋值给ViewModel的LinkedServices属性,再返回视图。这样视图就能拿到正确的选项集合,同时因为SelectedLinkedServiceId已经保存了用户提交的选中值,下拉框会自动选中对应的选项。
修改你的HttpPost控制器方法如下:
[HttpPost] public IActionResult Unregister(LinkedServiceTableViewModel vm) { // 先执行你的提交逻辑(比如取消注册操作) // 这里保留你原本的业务代码,例如: // _linkedServiceService.Unregister(vm.SelectedLinkedServiceId); // 重新构建LinkedServices选项列表,和HttpGet里的逻辑保持一致 var lst = new LinkedServiceTable(); lst.BuildLinkedServices(); vm.LinkedServices = GetLinkedServices(lst); return View(vm); }
额外优化方案(PRG模式)
如果你想遵循更规范的Web开发最佳实践,避免用户刷新页面重复提交表单,可以使用PRG(Post-Redirect-Get)模式:
- 提交成功后,把
SelectedLinkedServiceId存入TempData - 重定向回HttpGet的
Unregister方法 - 在HttpGet方法里读取
TempData中的ID,赋值给ViewModel的SelectedLinkedServiceId
示例代码:
[HttpPost] public IActionResult Unregister(LinkedServiceTableViewModel vm) { // 执行提交逻辑 // _linkedServiceService.Unregister(vm.SelectedLinkedServiceId); TempData["SelectedLinkedServiceId"] = vm.SelectedLinkedServiceId; return RedirectToAction(nameof(Unregister)); } [HttpGet] public IActionResult Unregister() { var lst = new LinkedServiceTable(); lst.BuildLinkedServices(); var model = new LinkedServiceTableViewModel { LinkedServices = GetLinkedServices(lst) }; // 读取TempData中的选中ID,设置到模型中 if (TempData.ContainsKey("SelectedLinkedServiceId")) { model.SelectedLinkedServiceId = int.Parse(TempData["SelectedLinkedServiceId"].ToString()); } return View(model); }
两种方法都能满足你的需求,第一种适合简单场景,第二种更健壮,能避免重复提交问题。
内容的提问来源于stack exchange,提问作者asdasd2a43qaad
相关产品推荐
相关产品推荐

