ASP.NET 5中GetPathByAction为Dictionary<string,string>生成错误查询参数问题
问题原因
这是ASP.NET Core LinkGenerator的已知设计局限,并非你的操作错误。
LinkGenerator的默认查询参数序列化逻辑仅对基础类型、一维数组等简单类型做了适配,没有和模型绑定的解析逻辑做对称实现:当传入的values中包含Dictionary类型对象时,默认仅会调用字典的ToString()方法输出序列化结果,你看到的myDict=[foo, bar]就是Dictionary<string,string>类型默认ToString()的输出。
首次生成链接时能得到符合模型绑定规则的myDict[foo]=bar格式,是因为首次生成时的values参数并非绑定后的字典对象,而是直接来自请求原始路由/查询参数的键值对集合。
可行解决方案
- 方案1:手动展平字典为符合绑定规则的键值对
生成URL前将字典的每一项转换为字典属性名[键]格式的键,和对应的值一起传入values参数,代替原字典对象,示例代码如下:
该方案生成的查询字符串格式和首次生成的完全一致,无需修改现有控制器的模型绑定逻辑。// 构造参数集合 var routeValues = new RouteValueDictionary { {"page", 2} }; // 展平MyDict字典 foreach (var kvp in yourModel.MyDict) { routeValues.Add($"MyDict[{kvp.Key}]", kvp.Value); } // 生成路径 var path = _linkGenerator.GetPathByAction(httpContextAccessor.HttpContext, null, null, routeValues); - 方案2:封装通用扩展方法
如果项目中多处需要生成带字典参数的URL,可以封装LinkGenerator的扩展方法,自动递归扫描传入的values参数中的字典类型属性,自动完成展平操作,避免重复编码。 - 方案3:JSON序列化传参
若字典项较多,可将整个字典序列化为JSON字符串作为单个查询参数传入,同时在控制器端添加自定义模型绑定器,将接收到的JSON字符串反序列化为Dictionary对象即可。该方案会降低URL的可读性,但适合字典结构复杂、项数多的场景。
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

