如何在Razor Pages中使用预定义选择列表实现级联下拉?
级联下拉列表实现修正方案
你的代码核心问题出在Razor Pages的请求生命周期、AJAX请求的防伪造验证,以及前后端数据属性的匹配上,以下是修正后的完整实现:
后端代码(Index.cshtml.cs)
public class IndexModel : PageModel { private readonly ILogger<IndexModel> _logger; private readonly Food2UContext _context; // 第一个下拉的选项 public IEnumerable<SelectListItem> UserTypeOptions => new[] { new SelectListItem {Text = "客户", Value = "Shoppers"}, new SelectListItem {Text = "配送员", Value = "DeliverPerson"}, new SelectListItem {Text = "餐厅", Value = "LocalRestaurants"}, }; public IndexModel(ILogger<IndexModel> logger, Food2UContext context) { _logger = logger; _context = context; } public void OnGet() { // 页面首次加载无需预加载所有列表,AJAX请求时按需查询即可 } // AJAX请求处理方法,按需查询数据库生成对应选项 public IActionResult OnGetFetchUserNames(string userType) { IEnumerable<SelectListItem> options = new List<SelectListItem>(); switch (userType) { case "Shoppers": var shoppers = _context.Shoppers.ToList(); options = shoppers.Select(s => new SelectListItem { Value = s.shopperID.ToString(), Text = s.Name }); break; case "DeliverPerson": var drivers = _context.DeliverPerson.ToList(); options = drivers.Select(d => new SelectListItem { Value = d.driverID.ToString(), Text = d.Name }); break; case "LocalRestaurants": var restaurants = _context.LocalRestaurants.ToList(); options = restaurants.Select(r => new SelectListItem { Value = r.restaurantID.ToString(), Text = r.Name }); break; } return new JsonResult(options); } }
前端代码(Index.cshtml)
<form method="post"> <div class="form-group w-25 mx-auto"> <!-- 修正下拉选项绑定方式 --> <select id="userTypeDropDown" asp-items="@Model.UserTypeOptions" class="form-control"> <option value="">-- 选择用户类型 --</option> </select> </div> <div class="form-group w-25 mx-auto"> <select id="userNameDropdown" name="users" class="form-control"> <option value="">-- 选择名称 --</option> </select> </div> <div class="form-group mt-3 text-center"> <input type="submit" value="继续" class="btn btn-secondary"> </div> </form> @section scripts{ <script> // 获取Razor Pages防伪造令牌,必须携带才能通过请求验证 const token = $('input[name="__RequestVerificationToken"]').val(); $("#userTypeDropDown").on("change", function () { var userType = $(this).val(); // 重置第二个下拉框 $("#userNameDropdown").empty().append('<option value="">-- 选择名称 --</option>'); if (!userType) return; // 未选择类型时直接终止 $.ajax({ method: 'get', url: '/Index?handler=FetchUserNames', headers: { "RequestVerificationToken": token }, data: {userType: userType }, success: function (res) { var htmlString = ""; // 匹配后端返回的Value和Text属性 $.each(res, function (k, v) { htmlString += `<option value='${v.Value}'>${v.Text}</option>`; }); $("#userNameDropdown").append(htmlString); }, error: function(xhr) { console.error("请求失败:", xhr.responseText); } }) }) </script> }
关键修正点说明
- 请求生命周期适配:原代码依赖
OnGet初始化的列表无法在AJAX请求中复用,因为每次HTTP请求都会创建新的IndexModel实例。修正后直接在AJAX处理方法中按需查询数据库,避免依赖页面加载时的属性。 - 防伪造验证支持:Razor Pages默认启用防伪造验证,AJAX请求必须在请求头中携带
RequestVerificationToken,否则会被400错误拦截。 - 前后端属性匹配:后端返回的
SelectListItem序列化后属性名为Value和Text,原前端代码错误使用v.val,导致无法正确渲染选项。 - 下拉绑定修正:原代码中
asp-items="IndexModel.userTypeOptions()"写法错误,改为@Model.UserTypeOptions匹配实例属性的绑定规则。
内容的提问来源于stack exchange,提问作者J D
相关产品推荐
相关产品推荐

