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

跨页面传递值作为路由参数的优选方案,实现下拉选择状态全局同步

实现方案

1. 统一配置全局路由模板

先给所有页面路由追加可选的branch参数,确保跳转任何页面都能携带该参数:

// Program.cs 中Razor Pages配置示例
builder.Services.AddRazorPages()
    .AddRazorPagesOptions(options =>
    {
        // 给根目录下所有页面的路由末尾添加可选branch参数
        options.Conventions.AddFolderRouteModelConvention("/", model =>
        {
            foreach (var selector in model.Selectors)
            {
                selector.AttributeRouteModel.Template += "/{branch?}";
            }
        });
    });
// 别忘了注册IHttpContextAccessor
builder.Services.AddHttpContextAccessor();

2. 封装BranchSelector视图组件

把下拉的查询、选中项绑定、跳转逻辑全部封装到视图组件,无需每个页面传递参数:

视图组件逻辑代码

// BranchSelectorViewComponent.cs
public class BranchSelectorViewComponent : ViewComponent
{
    private readonly YourDbContext _context;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public BranchSelectorViewComponent(YourDbContext context, IHttpContextAccessor httpContextAccessor)
    {
        _context = context;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        // 优先级:当前路由参数 > Cookie存储值
        var currentBranch = RouteData.Values["branch"]?.ToString() 
            ?? _httpContextAccessor.HttpContext.Request.Cookies["SelectedBranch"];
        
        // 替换为你获取当前用户ColleagueID的逻辑
        var userColleague = int.Parse(User.FindFirstValue("ColleagueID"));
        
        var options = await _context.BranchAssignment
            .Where(a => a.ColleagueID == userColleague)
            .IgnoreQueryFilters()
            .OrderBy(a => a.Branch.BranchNumber)
            .Select(a => new SelectListItem
            {
                Value = a.BranchID.ToString(),
                Text = a.Branch.BranchName,
                Selected = a.BranchID.ToString() == currentBranch
            })
            .ToListAsync();
        
        return View(options);
    }
}

视图组件页面代码

在Views/Shared/Components/BranchSelector/Default.cshtml中添加渲染和交互逻辑:

@model List<SelectListItem>

<select id="branchSelect" class="form-select" asp-items="Model" onchange="handleBranchChange(this.value)">
</select>

<script>
function handleBranchChange(selectedBranch) {
    const pathSegments = window.location.pathname.split('/').filter(seg => seg);
    let newPathSegments;

    // 替换已有branch参数,没有则追加
    if (pathSegments.length > 0 && !isNaN(pathSegments.at(-1))) {
        newPathSegments = [...pathSegments.slice(0, -1), selectedBranch];
    } else {
        newPathSegments = [...pathSegments, selectedBranch];
    }
    const newPath = '/' + newPathSegments.join('/');

    // 存储选中值到Cookie,有效期7天
    document.cookie = `SelectedBranch=${selectedBranch};path=/;max-age=${7 * 24 * 60 * 60};SameSite=Lax`;
    // 跳转到新地址
    window.location.href = newPath;
}
</script>

3. 全局挂载下拉组件

直接在_Layout.cshtml的导航栏位置引入视图组件,全局仅需引入一次:

<!-- 导航栏对应位置添加 -->
@await Component.InvokeAsync("BranchSelector")

4. 页面获取选中参数

各页面的OnGet方法直接从路由参数读取branch值即可:

public IActionResult OnGet(string branch)
{
    // 无路由参数时读取Cookie重定向补全路由
    if (string.IsNullOrEmpty(branch))
    {
        var savedBranch = Request.Cookies["SelectedBranch"];
        if (!string.IsNullOrEmpty(savedBranch))
        {
            return Redirect($"/{RouteData.Values["Page"]}/{savedBranch}");
        }
        // 无存储值时可跳转到默认branch或者提示选择
    }
    // 业务逻辑直接使用branch参数
    return Page();
}
方案优势
  • 逻辑完全复用:下拉的查询、渲染、交互全部封装在视图组件中,无需每个页面重复编写
  • 路由参数友好:选中值直接体现在URL中,用户分享链接时可直接携带选中的branch参数
  • 记忆逻辑可靠:同时通过路由和Cookie两层存储选中值,跳转不同页面自动继承选中状态
  • 符合业内常规实现:全局公共组件+路由参数+Cookie兜底的方案是后台系统多分支/多租户切换的常用实现方式

内容的提问来源于stack exchange,提问作者Colin-G-Davidson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:24:02