ASP.NET MVC Post请求下如何绑定表单字段到嵌套模型
问题背景
使用ASP.NET MVC+MediatR实现CQRS模式,表单提交后,UpdateApplicationCommand中嵌套的ApplicationEditGeneralViewModel字段值始终为null。需要保留嵌套结构以复用ApplicationEditGeneralViewModel,不希望将字段直接移至UpdateApplicationCommand类。
核心原因
当前视图的模型是ApplicationEditGeneralViewModel,表单生成的input元素name属性为Name、Description,但控制器接收的是UpdateApplicationCommand,其嵌套属性路径为ApplicationEditGeneralViewModel.Name,ASP.NET MVC的模型绑定无法自动匹配这种结构差异,导致嵌套对象为null。
简便解决方案
方案一:修改视图模型为UpdateApplicationCommand
直接将视图的模型改为UpdateApplicationCommand,表单中使用嵌套路径绑定字段,生成的name属性会自动匹配模型绑定要求:
@model UpdateApplicationCommand <form method="post" asp-action="Edit" asp-controller="Applications"> <div class="form-floating mb-3"> @Html.TextBoxFor(m => m.ApplicationEditGeneralViewModel.Name, new { @class = "form-control", placeholder = "Application Name"}) <label for="ApplicationEditGeneralViewModel_Name">Application Name</label> </div> <div class="form-floating mb-3"> @Html.TextBoxFor(m => m.ApplicationEditGeneralViewModel.Description, new { @class = "form-control", placeholder = "Application Description"}) <label for="ApplicationEditGeneralViewModel_Description">Application Description</label> </div> <div class="d-flex flex-row-reverse bd-highlight"> <input type="submit" value="Submit" class="btn btn-primary mt-2" /> </div> </form>
方案二:保留原视图模型,手动指定input的name属性
如果需要继续使用ApplicationEditGeneralViewModel作为视图模型,只需在TextBoxFor的html属性中手动指定符合嵌套结构的name值:
@model ApplicationEditGeneralViewModel <form method="post" asp-action="Edit" asp-controller="Applications"> <div class="form-floating mb-3"> @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "Application Name", name = "ApplicationEditGeneralViewModel.Name"}) <label for="Name">Application Name</label> </div> <div class="form-floating mb-3"> @Html.TextBoxFor(m => m.Description, new { @class = "form-control", placeholder = "Application Description", name = "ApplicationEditGeneralViewModel.Description"}) <label for="Description">Application Description</label> </div> <div class="d-flex flex-row-reverse bd-highlight"> <input type="submit" value="Submit" class="btn btn-primary mt-2" /> </div> </form>
验证效果
修改后提交表单,ASP.NET MVC的模型绑定会自动将表单值映射到UpdateApplicationCommand.ApplicationEditGeneralViewModel的对应字段中,无需拆分嵌套结构或添加额外路由配置。
内容的提问来源于stack exchange,提问作者Brian Chambers

