ASP.NET Core 6.0 MVC级联下拉框值无法存入数据库
ASP.NET Core 6 MVC级联下拉框提交后值无法存入数据库的问题分析与解决
问题描述
在ASP.NET Core 6.0 MVC中通过jQuery实现了分类-子分类、州-城市的级联下拉框,前端交互显示正常,但提交表单后所有下拉框的值都无法存入数据库。
核心原因分析
- 表单元素缺少
name属性:HTML的<select>标签若未设置name属性,表单提交时不会将选中值发送到后端,Model绑定无法获取对应数据。 - ViewBag与AJAX加载冲突:页面中同时使用
asp-items="ViewBag.Categories"和AJAX清空重加载下拉框,导致初始ViewBag渲染被覆盖;且AJAX请求中设置ViewBag无效(AJAX不刷新页面,ViewBag仅在页面首次加载时生效)。 - 后端查询逻辑错误:
GetSubCategory中查询条件写成x.SubCategoryId == id,实际应为子分类关联的分类ID(x.CategoryId == id),导致无法正确获取子分类数据。 - jQuery语法与属性名错误:初始禁用下拉框时使用未定义的
state变量,且属性名拼写错误(disable应为disabled);AJAX渲染选项时属性名不匹配(如子分类用data.id而非实体的SubCategoryId)。
修复步骤
1. 给下拉框添加name属性
修改CSHTML中的<select>标签,添加与Model属性名一致的name属性:
<div class="col"> <label>Category</label> <select class="form-control" id="category" name="CategoryId" style="background-color: transparent"></select> </div> <div class="col"> <label>Sub Category</label> <select id="subCategory" name="SubCategoryId" class="form-control" style="background-color: transparent"></select> </div>
注:
name值需与实体类属性名完全对应,如实体属性为SelectedCategoryId,则name="SelectedCategoryId"
2. 移除无效的asp-items绑定
由于下拉框通过AJAX动态加载选项,asp-items会被AJAX清空覆盖,直接删除该属性避免冲突。
3. 修正后端Action逻辑
修正GetSubCategory查询条件:
public JsonResult GetSubCategory(int id) { // 修正查询条件:子分类关联分类ID,而非自身ID var subCategories = _context.PropertySubCategories .Where(x => x.CategoryId == id) .OrderBy(x => x.SubCategoryName) .ToList(); // AJAX请求无需设置ViewBag,直接返回JSON数据 return new JsonResult(subCategories); }
简化GetCategory逻辑:
public JsonResult GetCategory() { var categories = _context.PropertyCategories.ToList(); // 移除无效的ViewBag设置 return new JsonResult(categories); }
4. 修正jQuery代码错误
修复初始禁用下拉框的语法:
$(document).ready(function () { // 使用#id选择器,属性名修正为disabled $('#state').attr('disabled', true); $('#city').attr('disabled', true); $('#category').attr('disabled', true); $('#subCategory').attr('disabled', true); LoadStates(); LoadCategory(); // ... 其余逻辑 });
修正子分类选项的属性名:
function LoadSubCategory(categoryId) { $('#subCategory').empty(); $.ajax({ url: '/PropertListing/GetSubCategory?id=' + categoryId, success: function (response) { if (response != null && response != undefined && response.length > 0) { $('#subCategory').attr('disabled', false); $('#subCategory').append('<option>--Select Sub Category--</option>'); $.each(response, function (i, data) { // 使用实体对应的SubCategoryId作为value值 $('#subCategory').append('<option value=' + data.subCategoryId + '>' + data.subCategoryName + '</option>'); }); } // ... 错误处理逻辑 } }); }
同理修正城市加载的属性名(若实体城市ID为CityId):
$.each(response, function (i, data) { $('#city').append('<option value=' + data.cityId + '>' + data.cityName + '</option>'); });
5. 确保Model绑定正确
后端接收表单的Action参数需与下拉框name属性对应:
[HttpPost] public IActionResult Create(PropertyViewModel model) { if (ModelState.IsValid) { // 此时model.CategoryId、model.SubCategoryId等属性应已正确获取值 _context.Property.Add(model); _context.SaveChanges(); return RedirectToAction(nameof(Index)); } return View(model); }
总结
核心问题是表单元素缺少name属性导致值无法提交,辅以AJAX加载时的属性名不匹配、语法错误及无效ViewBag使用。按照上述步骤修复后,下拉框值即可正常存入数据库。
内容的提问来源于stack exchange,提问作者Mayank Srivastava
相关产品推荐
相关产品推荐

