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

ASP.NET中按用户角色加载asp-items下拉列表并存Session的空值问题

问题根因

下拉框始终为空是三个核心错误导致的:

  • Selection属性声明后从未初始化,默认值为null。直接调用Selection.Add()时会触发空引用异常,若项目未配置显式异常捕获,会静默失败,Selection始终是无内容的空引用,自然无法给asp-items提供绑定数据。
  • Session存储逻辑完全失效:仅在权限值为10的分支中尝试拼接选项内容,其余权限分支完全没有写入选项的逻辑;且所有分支执行到最后,都会把UserRoleMessage覆盖为纯数字的权限值,之前写入的选项内容会被直接覆盖。另外直接用string.Join拼接SelectListItem对象,只会得到类型全名字符串,完全不包含选项的Value、Text信息,存了也无法复用。
  • 缺少跨请求重绑逻辑:Razor Pages不会自动在回发请求中保留SelectList数据,表单提交后如果没有重新填充Selection就返回页面,绑定源会直接为空。
正确实现步骤

1. 初始化集合属性,修正权限判断逻辑

声明属性时直接初始化集合,从根源避免空引用,同时将独立的if判断改为else if互斥逻辑,避免后续权限值调整时出现重复添加选项的问题:

// 初始化集合,杜绝空引用
public List<SelectListItem> Selection { get; set; } = new List<SelectListItem>();
// 绑定下拉框选中值的属性
public string SelectedRole { get; set; }
public string UserRoleMessage { get; set; }

2. 修正后端加载与Session存储逻辑

每次加载选项前先清空历史数据,存储选项时用JSON序列化保证数据完整,不要直接拼接对象:

public IActionResult OnGetRecht()
{
    // 清空历史选项,避免重复添加
    Selection.Clear();

    // 按权限等级加载对应选项
    if (UserModel.RECHT == 50)
    {
        Selection.AddRange(new []
        {
            new SelectListItem { Value = "SY", Text = "System" },
            new SelectListItem { Value = "AD", Text = "Admin" },
            new SelectListItem { Value = "ID", Text = "Innendienst" },
            new SelectListItem { Value = "SP", Text = "Spediteur" },
            new SelectListItem { Value = "DS", Text = "Disponent" }
        });
    }
    else if (UserModel.RECHT == 40)
    {
        Selection.AddRange(new []
        {
            new SelectListItem { Value = "AD", Text = "Admin" },
            new SelectListItem { Value = "ID", Text = "Innendienst" },
            new SelectListItem { Value = "SP", Text = "Spediteur" },
            new SelectListItem { Value = "DS", Text = "Disponent" }
        });
    }
    else if (UserModel.RECHT == 30)
    {
        Selection.AddRange(new []
        {
            new SelectListItem { Value = "ID", Text = "Innendienst" },
            new SelectListItem { Value = "SP", Text = "Spediteur" },
            new SelectListItem { Value = "DS", Text = "Disponent" }
        });
    }
    else if (UserModel.RECHT == 20)
    {
        Selection.AddRange(new []
        {
            new SelectListItem { Value = "SP", Text = "Spediteur" },
            new SelectListItem { Value = "DS", Text = "Disponent" }
        });
    }
    else if (UserModel.RECHT == 10)
    {
        Selection.Add(new SelectListItem { Value = "DS", Text = "Disponent" });
    }

    // 序列化选项列表存入Session,保证数据可复用
    var optionsJson = System.Text.Json.JsonSerializer.Serialize(Selection);
    HttpContext.Session.SetString("UserRoleOptions", optionsJson);
    // 单独存储用户权限标识
    UserRoleMessage = UserModel.RECHT.ToString();
    HttpContext.Session.SetString("UserRoleMessage", UserRoleMessage);

    return Page();
}

3. 前端绑定配置

在cshtml页面中按下述方式绑定下拉框,注意添加默认空选项提升可用性:

<select asp-for="SelectedRole" asp-items="Model.Selection" class="form-control">
    <option value="">请选择对应角色</option>
</select>

注意事项:如果页面存在POST提交处理逻辑,在调用return Page()返回视图前,必须重新执行一次选项填充逻辑(可以直接从Session反序列化之前存储的选项数据赋值给Selection,不需要重复判断权限),否则回发后下拉框会再次因绑定源为空不显示内容。

附:Session读取复用方法

其他页面/处理方法需要用到这套角色选项时,直接从Session反序列化即可:

private void PopulateSelectionFromSession()
{
    var sessionData = HttpContext.Session.GetString("UserRoleOptions");
    if (!string.IsNullOrWhiteSpace(sessionData))
    {
        Selection = System.Text.Json.JsonSerializer.Deserialize<List<SelectListItem>>(sessionData);
    }
}

内容的提问来源于stack exchange,提问作者Mariam Bari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:51:29