ASP.NET Core 3.1中使用asp-for属性POST后值未设置的问题
问题原因与解决方案
这个问题我碰到过好多次啦!核心原因是ASP.NET(Core)的ModelState优先级规则:当使用asp-for生成表单元素时,框架会优先从ModelState中读取值,而不是直接使用你在控制器里更新后的ViewModel属性值。
具体来说,你的POST请求里并没有提交Result字段的值(因为它是只读的plaintext输入框,表单提交时不会把这个值发回服务器),所以ModelState里Result对应的条目还是初始的空值。哪怕你在控制器里给model.Result赋值了DoSomething()的返回值,asp-for="Result"依然会优先取ModelState里的旧值(空),而不是ViewModel的新值——但直接用@Model.Result输出时,是直接读取ViewModel的属性,所以能正常显示。
解决方法有这几种,按推荐程度排序:
1. 移除ModelState中Result的条目(最推荐)
在控制器里设置完model.Result后,把Result从ModelState中移除,这样asp-for就会转而读取ViewModel的属性值:
[HttpPost] [ValidateAntiForgeryToken] public IActionResult Index(GogViewModel model) { if (ModelState.IsValid) { model.Result = DoSomething(); // 移除ModelState里的Result条目,让asp-for读取ViewModel的新值 ModelState.Remove("Result"); } return View(model); }
2. 直接给input设置value属性
如果你不想操作ModelState,也可以直接放弃asp-for的自动绑定,手动给input设置value:
<input type="text" class="form-control-plaintext" readonly="readonly" value="@Model.Result" />
这种方式简单直接,适合只读字段的场景。
3. 清空整个ModelState(不推荐)
你也可以直接清空整个ModelState,但这样会丢失其他字段的验证状态(比如Name的必填验证提示),所以除非你不需要保留验证信息,否则不建议用:
[HttpPost] [ValidateAntiForgeryToken] public IActionResult Index(GogViewModel model) { if (ModelState.IsValid) { model.Result = DoSomething(); // 清空所有ModelState,不推荐,会丢失验证信息 ModelState.Clear(); } return View(model); }
内容的提问来源于stack exchange,提问作者Snake Eyes
相关产品推荐
相关产品推荐

