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

Dictionary替代方案:ASP.NET Core中重复键与asp-all-route-data适配问题

解决Dictionary重复键错误并适配多值路由参数与模型绑定

核心问题

执行CurrentFilters.Add($"Colors", Colors[i].ToString());时触发重复键错误,因为Dictionary<string, string>不允许同一键多次添加;而asp-all-route-data仅支持IDictionary<string, string>类型,无法直接生成Colors=red&Colors=blue这类多值URL参数,同时模型绑定要求键名为Colors才能正确接收多值列表。

解决方案

方案1:自定义扩展方法生成多值查询字符串

放弃直接使用asp-all-route-data,通过扩展方法将多值字典转换为符合要求的查询字符串:

  1. 修改后端模型属性类型
    将CurrentFilters改为Dictionary<string, List<string>>,用于存储多值参数:

    public Dictionary<string, List<string>> CurrentFilters { get; set; } = new();
    

    在OnGetAsync中添加参数时,直接向对应键的列表中添加值:

    // 初始化单值参数
    CurrentFilters["SearchString"] = new List<string> { SearchString };
    CurrentFilters["SortOrder"] = new List<string> { SortOrder };
    // 添加多值Colors
    if (Colors != null && Colors.Any())
    {
        CurrentFilters["Colors"] = Colors.ToList();
    }
    
  2. 添加查询字符串生成扩展方法
    创建静态类实现字典转查询字符串的逻辑,处理多值参数:

    public static class RouteDataExtensions
    {
        public static string ToQueryString(this Dictionary<string, List<string>> routeData)
        {
            var queryItems = new List<string>();
            foreach (var kvp in routeData)
            {
                foreach (var value in kvp.Value.Where(v => !string.IsNullOrEmpty(v)))
                {
                    queryItems.Add($"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(value)}");
                }
            }
            return queryItems.Any() ? $"?{string.Join("&", queryItems)}" : string.Empty;
        }
    }
    
  3. 前端使用扩展方法生成URL
    在<a>标签中直接调用扩展方法生成完整查询字符串:

    <a href="/Index@Model.CurrentFilters.ToQueryString()">应用筛选</a>
    

    此方式会生成目标格式的URL:localhost234/Index?SearchString=text&Colors=red&Colors=blue&SortOrder=Colors_asc,后端List<string> Colors属性可直接完成模型绑定。

方案2:使用QueryBuilder构造查询字符串

若不想修改CurrentFilters的类型,可通过QueryBuilder手动拼接包含多值的查询参数:

  1. 后端构造查询字符串
    在OnGetAsync中生成查询字符串并存储到模型属性:

    public string FilterQueryString { get; set; }
    
    public async Task OnGetAsync()
    {
        var queryBuilder = new QueryBuilder();
        // 添加单值参数
        if (!string.IsNullOrEmpty(SearchString))
        {
            queryBuilder.Add("SearchString", SearchString);
        }
        if (!string.IsNullOrEmpty(SortOrder))
        {
            queryBuilder.Add("SortOrder", SortOrder);
        }
        // 添加多值Colors
        if (Colors != null && Colors.Any())
        {
            foreach (var color in Colors)
            {
                queryBuilder.Add("Colors", color);
            }
        }
        FilterQueryString = queryBuilder.ToString();
    }
    
  2. 前端直接使用生成的查询字符串

    <a href="/Index@Model.FilterQueryString">应用筛选</a>
    

关键说明

  • asp-all-route-data仅支持IDictionary<string, string>,无法生成同一键的多个参数,因此必须通过自定义逻辑绕过此限制。
  • 后端模型中需声明List<string> Colors属性,ASP.NET Core会自动将URL中多个Colors参数绑定到该列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:25:11