You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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>
}

关键修正点说明

  1. 请求生命周期适配:原代码依赖OnGet初始化的列表无法在AJAX请求中复用,因为每次HTTP请求都会创建新的IndexModel实例。修正后直接在AJAX处理方法中按需查询数据库,避免依赖页面加载时的属性。
  2. 防伪造验证支持:Razor Pages默认启用防伪造验证,AJAX请求必须在请求头中携带RequestVerificationToken,否则会被400错误拦截。
  3. 前后端属性匹配:后端返回的SelectListItem序列化后属性名为Value和Text,原前端代码错误使用v.val,导致无法正确渲染选项。
  4. 下拉绑定修正:原代码中asp-items="IndexModel.userTypeOptions()"写法错误,改为@Model.UserTypeOptions匹配实例属性的绑定规则。

内容的提问来源于stack exchange,提问作者J D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:09:31