MVC BeginCollectionItem分部视图数据无法保存至数据库的问题咨询
Absolutely! You can absolutely use the [Bind] attribute to resolve this issue—it’s a go-to approach when working with dynamic collections built using BeginCollectionItem. Let’s break down exactly how to make this work for your scenario:
1. First, Confirm Your Model Structure
Make sure your main view model includes a collection property for your sections, and your section view model has the necessary fields (like the name input):
// Main view model that wraps the collection public class ProjectViewModel { public int Id { get; set; } public List<SectionViewModel> Sections { get; set; } = new List<SectionViewModel>(); } // Individual section view model public class SectionViewModel { public string SectionName { get; set; } }
2. Use [Bind] in Your Controller's POST Action
In your POST method, explicitly define which properties to bind—this ensures the dynamic collection data is correctly mapped to your model. You’ll need to reference the collection property and its child fields using dot notation:
[HttpPost] public IActionResult SaveProject([Bind("Id,Sections.SectionName")] ProjectViewModel model) { // First check if model state is valid (this catches binding issues) if (ModelState.IsValid) { // Map view model data to your database entities var project = new Project { Id = model.Id }; project.Sections = model.Sections.Select(s => new Section { Name = s.SectionName }).ToList(); // Save to database _context.Projects.Add(project); _context.SaveChanges(); return RedirectToAction(nameof(Index)); } // If invalid, return to the form with errors return View(model); }
3. Verify Your Partial View's Form Fields
Ensure your partial view uses asp-for correctly to generate the right input names (BeginCollectionItem handles the unique index for you, but asp-for ensures the field is tied to the collection):
@model SectionViewModel <div class="dynamic-section"> @using (Html.BeginCollectionItem("Sections")) { <div class="mb-3"> <label asp-for="SectionName" class="form-label">Section Name</label> <input asp-for="SectionName" class="form-control" /> <span asp-validation-for="SectionName" class="text-danger"></span> </div> <button type="button" class="btn btn-sm btn-danger remove-section">Remove Section</button> } </div>
4. Debugging Tips if It Still Doesn't Work
- Check
ModelState.IsValidin your POST action. If it’s false, inspect the errors withModelState.Values.SelectMany(v => v.Errors)—this will tell you exactly which fields aren’t binding correctly. - Use your browser’s DevTools (Network tab) to look at the form data being submitted. You should see entries like
Sections[abc123-guid-here].SectionName—this confirms BeginCollectionItem is generating the right field names, and your[Bind]setup should pick these up. - If you have other properties in your main view model, don’t forget to add them to the
[Bind]list (e.g.,[Bind("Id,ProjectName,Sections.SectionName")])—otherwise those values won’t be bound.
This approach should get your dynamic section data saving to the database without issues. The key is making sure your [Bind] attribute includes the full path to your collection’s child properties, matching what BeginCollectionItem generates in the form fields.
内容的提问来源于stack exchange,提问作者Lucy Foster

