手动修改模型后调用UpdateModel报错:无法更新指定类型模型
解决UpdateModel报错的问题
我来帮你分析下问题所在,以及怎么解决:
首先,你遇到的核心问题是UpdateModel方法会尝试把请求中的所有数据绑定到模型上,但你手动赋值的SexList、DoctorList、TestList这些字段,请求里根本没有对应的提交数据,模型绑定器找不到这些值,就会抛出更新失败的错误。之前你只处理了TestList的ModelState,但其他几个手动赋值的字段同样会触发绑定错误。
直接有效的解决方案:
不需要调用UpdateModel!因为你的模型model已经通过Action参数完成了请求数据的绑定,你只是手动补充了几个视图需要的列表和生成的Serial值,这时候直接验证ModelState.IsValid就可以了,完全没必要再调用UpdateModel去重复绑定。
修改后的控制器代码可以这样写:
public ActionResult CreateEntry(NewEntryViewModel model) { // 手动补充模型中请求未提供的数据 model.SexList = new SelectList(_newEntryService.GetSexList(), "Key", "Value"); model.DoctorList = new SelectList(_refDocService.GetDocList(), "Key", "Value"); model.TestList = _testService.GetAllTests(); model.Patient.Serial = _newEntryService.GenerateSerial(); // 移除手动赋值字段的ModelState,避免验证时把这些字段的绑定缺失当成错误 ModelState.Remove("SexList"); ModelState.Remove("DoctorList"); ModelState.Remove("TestList"); ModelState.Remove("Patient.Serial"); // 直接验证模型有效性 if (!ModelState.IsValid) { // 可以在这里输出错误排查 var errors = ModelState .Where(x => x.Value.Errors.Count > 0) .Select(x => new { x.Key, x.Value.Errors }) .ToArray(); return View("NewEntry", model); } return RedirectToAction("NewEntry"); }
为什么之前的尝试没用?
- 你只清除了
TestList的错误,但SexList、DoctorList这些同样是手动赋值的字段,请求里没有它们的数据,模型绑定器依然会标记这些字段的绑定错误。 ModelState["TestList"].Errors.Clear()只是清除已有的错误,但后续如果触发绑定(比如调用UpdateModel),绑定器还是会因为找不到请求数据而生成新的错误。
如果一定要用UpdateModel怎么办?
如果你有特殊需求必须调用UpdateModel,那就要明确告诉它跳过那些手动赋值的字段,不要尝试绑定它们:
// 移除手动赋值字段的ModelState ModelState.Remove("SexList"); ModelState.Remove("DoctorList"); ModelState.Remove("TestList"); ModelState.Remove("Patient.Serial"); // 调用UpdateModel时排除这些字段 UpdateModel(model, excludeProperties: new[] { "SexList", "DoctorList", "TestList", "Patient.Serial" });
这样UpdateModel只会处理请求中存在的字段,不会碰你手动设置的内容,也就不会报错了。
内容的提问来源于stack exchange,提问作者Wahid Masud
相关产品推荐
相关产品推荐

