ASP.NET Core 7 MVC中JQuery Ajax级联下拉菜单返回undefined问题
级联下拉菜单子分类返回undefined问题
我在学习构建ASP.NET Core 7级联下拉菜单时,参考了相关示例和教程,但子分类下拉菜单始终返回undefined值。已定位问题到JSON返回类型,但未找到解决办法。
相关代码
DisplayCategories.cshtml
@{ ViewBag.Title = "Cascading DropDownList example in ASP.NET MVC - GeeksArray.com"; } <h2>Cascading DropDownList example in ASP.NET MVC - GeeksArray.com</h2> @using (Html.BeginForm("CategoryChosen", "Home", FormMethod.Get)) { <table cellspacing="2" cellpadding="2"> <tr> <td> Category Type : </td> <td> @Html.DropDownList("CategoryType") </td> </tr> <tr> <td> Sub Category: </td> <td> @Html.DropDownList("SubCategory", new SelectList(string.Empty, "Value", "Text"), "Please select a Sub Category", new { style = "width:250px" }) </td> </tr> </table> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function () { $("#CategoryType").change(function () { $("#SubCategory").empty(); $.ajax({ type: 'POST', url: '@Url.Action("GetSubCategories")', dataType: 'json', data: { id: $("#CategoryType").val() }, success: function (subcategories) { $.each(subcategories, function (i, subcategory) { $("#SubCategory").append('<option value="' + subcategory.Value + '">' + subcategory.Text + '</option>'); }); }, error: function (ex) { alert('Failed to retrieve Sub Categories : ' + ex); } }); return false; }) }); </script> }
HomeController.cs
public ActionResult DisplayCategories() { List<SelectListItem> items = new List<SelectListItem>(); items.Add(new SelectListItem { Text = "Select Category", Value = "0", Selected = true }); items.Add(new SelectListItem { Text = "Beverage", Value = "1" }); items.Add(new SelectListItem { Text = "Condiment", Value = "2" }); items.Add(new SelectListItem { Text = "Confection", Value = "3" }); items.Add(new SelectListItem { Text = "Dairy", Value = "4" }); items.Add(new SelectListItem { Text = "Grains", Value = "5" }); items.Add(new SelectListItem { Text = "Meat", Value = "6" }); items.Add(new SelectListItem { Text = "Produce", Value = "7" }); items.Add(new SelectListItem { Text = "Seafood", Value = "8" }); ViewBag.CategoryType = items; return View(); } public JsonResult GetSubCategories(string id) { List<SelectListItem> subCategories = new List<SelectListItem>(); subCategories.Add(new SelectListItem { Text = "Select", Value = "0" }); switch (id) { case "1": subCategories.Add(new SelectListItem { Text = "Coffee", Value = "1" }); subCategories.Add(new SelectListItem { Text = "Energy", Value = "2" }); subCategories.Add(new SelectListItem { Text = "Tea", Value = "3" }); subCategories.Add(new SelectListItem { Text = "Cold", Value = "4" }); break; case "2": subCategories.Add(new SelectListItem { Text = "Garlic", Value = "1" }); subCategories.Add(new SelectListItem { Text = "Pickles", Value = "2" }); subCategories.Add(new SelectListItem { Text = "Raita", Value = "3" }); subCategories.Add(new SelectListItem { Text = "Sauce", Value = "4" }); break; case "3": subCategories.Add(new SelectListItem { Text = "Desserts", Value = "1" }); subCategories.Add(new SelectListItem { Text = "Sweet", Value = "2" }); break; case "4": subCategories.Add(new SelectListItem { Text = "Cheese", Value = "1" }); break; case "5": subCategories.Add(new SelectListItem { Text = "Crackers", Value = "1" }); subCategories.Add(new SelectListItem { Text = "Pasta", Value = "2" }); break; case "6": subCategories.Add(new SelectListItem { Text = "Prepared", Value = "1" }); break; case "7": subCategories.Add(new SelectListItem { Text = "Dried Fr", Value = "1" }); break; case "8": subCategories.Add(new SelectListItem { Text = "Fish", Value = "1" }); subCategories.Add(new SelectListItem { Text = "Crab", Value = "2" }); break; default: subCategories.Add(new SelectListItem { Text = "Coffee", Value = "1" }); subCategories.Add(new SelectListItem { Text = "Tea", Value = "3" }); subCategories.Add(new SelectListItem { Text = "Colddrinks", Value = "4" }); break; } return Json(new SelectList(subCategories, "Value", "Text")); }
调试情况
- 手动修改前端代码为固定值时,子分类下拉菜单可正常填充:
$.each(subcategories, function (i, subcategory) { $("#SubCategory").append('<option value="5">Testing</option>'); });
- 后端调试可见
switch语句中subCategories列表已正确填充,但JSON返回数据存在问题,导致前端无法读取subcategory.Value和subcategory.Text。
解决方案
问题根源在于后端返回的JSON结构与前端期望的属性名不匹配:
方法1:修改前端代码适配驼峰属性名
ASP.NET Core默认序列化会将SelectListItem的Value和Text转为驼峰式的value和text,因此调整前端循环代码:
$.each(subcategories, function (i, subcategory) { $("#SubCategory").append('<option value="' + subcategory.value + '">' + subcategory.text + '</option>'); });
方法2:后端直接返回List<SelectListItem>
取消SelectList包装,直接返回原始列表,这样序列化后的属性名会保留Value和Text,前端无需修改:
return Json(subCategories);
额外注意:ASP.NET Core中POST请求需处理CSRF验证,可在表单内添加@Html.AntiForgeryToken(),并在AJAX请求中加入请求头:
headers: { RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val() }
同时在GetSubCategories方法上添加[ValidateAntiForgeryToken]特性。
内容的提问来源于stack exchange,提问作者Robert Frame
相关产品推荐
相关产品推荐

