ASP.NET Core MVC HttpPost提交更新时Model ID始终为0
问题根因与修复方案
核心触发原因
该问题完全由ASP.NET Core默认模型绑定的嵌套属性字段名匹配规则导致,本质是你手动修改了Razor TagHelper自动生成的表单属性,破坏了绑定路径:
- 你的POST Action接收的参数是
ExpenseVM obj,属于带嵌套结构的视图模型:层级为ExpenseVM属性Expense-> 业务实体属性Id。 - 模型绑定要为
obj.Expense.Id赋值,要求表单提交的字段名必须严格匹配层级路径,也就是字段名必须是Expense.Id。 - 你写隐藏域时,
asp-for="Expense.Id"本来会自动生成符合要求的name="Expense.Id",但你额外手动添加了name="Id",直接覆盖了TagHelper生成的正确属性。最终生成的HTML字段名是顶层的Id,完全匹配不到嵌套属性的路径要求,模型绑定无法获取对应值,就会为int类型的Id赋默认值0。
正确修改方式
直接移除手动添加的冗余属性,不要干预Razor TagHelper的自动生成逻辑即可,最终正确的隐藏域代码为:
<input type="hidden" asp-for="Expense.Id" />
这种写法下框架会自动完成所有必要逻辑:
- 生成匹配模型绑定要求的
name="Expense.Id"字段名 - 自动从视图模型读取
Model.Expense.Id的值作为隐藏域的value - 自动生成对应的元素id、数据校验属性,完全不需要手写value、name属性。
注意:如果是早期直接将业务实体作为Action参数的写法(比如
public IActionResult Update(Expense obj)),表单字段用name="Id"是可以正常绑定的,但只要参数换成了带嵌套属性的ViewModel,就必须遵循嵌套属性的层级命名规则,不能直接照搬之前的顶层字段名写法。
内容的提问来源于stack exchange,提问作者Aspirio
相关产品推荐
相关产品推荐

