ASP.NET一对多模型绑定失败问题排查及解决
问题描述
我正在为一对多(实际由两个一对多关系构成多对多)实体创建表单,提交时Model Binder绑定失败,提交字段无法映射到模型,原因不明。创建表单显示正常,提交数据如下:
facility.Name: TEST facility.Code: TST facility.RegionCode: AB departmentFacility[0].DepartmentCode: ARR departmentFacility[0].PrimaryRouterId: 4 departmentFacility[0].SecondaryRouterId: 1 departmentFacility[1].DepartmentCode: TFG departmentFacility[1].PrimaryRouterId: 1 departmentFacility[1].SecondaryRouterId: 4 __RequestVerificationToken: *<removed>* facility.Active: false
模型
public class FacilityViewModel { [Required] public string Name { get; set; } [Required] [StringLength(3)] public string Code { get; set; } [Required] public Boolean Active { get; set; } public string RegionCode { get; set; } public virtual ICollection<DepartmentFacilityViewModel> DepartmentFacilities { get; set; } } public class DepartmentFacilityViewModel { public string DepartmentCode { get; set; } public int PrimaryRouterId { get; set; } public int SecondaryRouterId { get; set; } } public class FacilityDepartment { public IList<DepartmentFacilityViewModel> departmentFacility { get; set; } public FacilityViewModel facility { get; set; } }
视图
@using TEST.Models.FacilityViewModels @model TEST.Models.FacilityViewModels.FacilityDepartment @{ ViewData["Title"] = "Create Facility"; } <h1>Create</h1> <h4>Facility</h4> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="Create"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="@Model.facility.Name" class="control-label"></label> <input asp-for="@Model.facility.Name" class="form-control" /> <span asp-validation-for="@Model.facility.Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="@Model.facility.Code" class="control-label"></label> <input asp-for="@Model.facility.Code" class="form-control" /> <span asp-validation-for="@Model.facility.Code" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="@Model.facility.RegionCode" class="control-label"></label> <input asp-for="@Model.facility.RegionCode" class="form-control" /> <span asp-validation-for="@Model.facility.RegionCode" class="text-danger"></span> </div> <div class="form-group form-check"> <label class="form-check-label"> <input class="form-check-input" asp-for="@Model.facility.Active" /> @Html.DisplayNameFor(model => model.facility.Active) </label> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <table> <thead><th>Department</th><th>Primary Router</th><th>Secondary Router</th></thead> <tbody> @{ int cnt = 0; List<FacilityDepartmentData> departments = ViewBag.Departments; foreach (var department in departments) { @:<tr><td> <input type="checkbox" name="@($"departmentFacility[{cnt}].DepartmentCode")" value="@department.DepartmentCode" class="form-check-input" @(Html.Raw(department.Assigned ? "checked=\"checked\"" : "")) /> @department.DepartmentName @:</td> @:<td> <select asp-for="@department.PrimaryRouterId" name="@($"departmentFacility[{cnt}].PrimaryRouterId")" id="@($"departmentFacility{cnt}_PrimaryRouterId")" class="form-control" asp-items="ViewBag.RegionRouters"><option disabled selected>--- SELECT ---</option></select> @:</td> @:<td> <select asp-for="@department.SecondaryRouterId" name="@($"departmentFacility[{cnt}].SecondaryRouterId")" id="@($"departmentFacility{cnt}_SecondaryRouterId")" class="form-control" asp-items="ViewBag.RegionRouters"><option disabled selected>--- SELECT ---</option></select> @:</td></tr> cnt++; } } </tbody> </table> </div> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> </div> </div>
控制器(原代码)
public IActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(FacilityDepartment facility) { if (ModelState.IsValid) { _context.Add(facility); if (!ModelState.IsValid) { return View(facility); } await _context.SaveChangesAsync(User.Identity?.Name); return RedirectToAction(nameof(Index)); } return View(facility); }
问题解决(更新)
通过修改控制器代码解决了绑定问题,修改后的代码如下:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(FacilityDepartment facilityDepartment) { if (ModelState.IsValid) { // 将facilityDepartment映射为实体类 Facility fac = new Facility(); fac.Name = facilityDepartment.facility.Name; fac.Code = facilityDepartment.facility.Code; fac.Active = facilityDepartment.facility.Active; fac.RegionCode = facilityDepartment.facility.RegionCode; fac.DepartmentFacilities = new List<DepartmentFacility>(); foreach (var department in facilityDepartment.departmentFacility) { if (department is not null) { var D = new DepartmentFacility() { PrimaryRouterId = department.PrimaryRouterId, SecondaryRouterId = department.SecondaryRouterId, DepartmentCode = department.DepartmentCode }; fac.DepartmentFacilities.Add(D); } } _context.Facilities.Add(fac); if (!ModelState.IsValid) { return View(facilityDepartment); } await _context.SaveChangesAsync(User.Identity?.Name); return RedirectToAction(nameof(Index)); } return View(facilityDepartment); }
内容的提问来源于stack exchange,提问作者matthewprobasco
相关产品推荐
相关产品推荐

