如何使用asp-route传递数组?ASP.NET Core路由传参问题
解决ASP.NET Razor Pages中asp-route传递数组参数的问题
问题说明
- 通过form提交数组参数时,URL格式为
localhost2343/index?Colors=red&Colors=blue&Colors=pink,功能正常 - 使用
<a>标签的asp-route-Colors="@Model.Colors"生成URL时,数组参数会被转为Colors=System.String%5B%5D(即数组默认的ToString()结果) - 尝试用
asp-all-route-data传递字典时,不仅丢失了Sort变量,还只能传递单个Colors值
可行解决方案
方法1:手动拼接查询字符串
直接在视图中构建完整的查询参数,包含数组的每一项:
@{ var queryParams = new List<string>(); // 添加排序参数 if (!string.IsNullOrEmpty(Model.Colors_Sort)) { queryParams.Add($"SortOrder={Uri.EscapeDataString(Model.Colors_Sort)}"); } // 添加搜索字符串 if (!string.IsNullOrEmpty(Model.SearchString)) { queryParams.Add($"SearchString={Uri.EscapeDataString(Model.SearchString)}"); } // 遍历Colors数组添加参数 if (Model.Colors != null && Model.Colors.Length > 0) { foreach (var color in Model.Colors) { if (!string.IsNullOrEmpty(color)) { queryParams.Add($"Colors={Uri.EscapeDataString(color)}"); } } } // 拼接成完整URL var queryString = string.Join("&", queryParams); var fullUrl = Url.Page("./Index") + (queryString.Length > 0 ? $"?{queryString}" : ""); } <a href="@fullUrl"> @Html.DisplayNameFor(model => model.MyList[0].Colors) </a>
方法2:自定义路由值转换器(优雅复用)
通过自定义路由值转换器,自动处理数组参数的格式转换:
- 添加自定义转换器类:
using Microsoft.AspNetCore.Routing; using System.Collections.Generic; using System.Linq; public class ArrayRouteValueTransformer : DynamicRouteValueTransformer { public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values) { var transformedValues = new RouteValueDictionary(values); // 处理Colors数组参数 if (transformedValues.TryGetValue("Colors", out var colorsObj) && colorsObj is string[] colors) { transformedValues.Remove("Colors"); foreach (var color in colors) { transformedValues.Add("Colors", color); } } return new ValueTask<RouteValueDictionary>(transformedValues); } }
- 在
Program.cs中注册转换器:
builder.Services.AddSingleton<DynamicRouteValueTransformer, ArrayRouteValueTransformer>();
- 视图中正常使用
asp-route:
<a asp-page="./Index" asp-route-SortOrder="@Model.Colors_Sort" asp-route-SearchString="@Model.SearchString" asp-route-Colors="@Model.Colors"> @Html.DisplayNameFor(model => model.MyList[0].Colors) </a>
方法3:修复asp-all-route-data的使用
普通Dictionary不允许重复键,改用RouteValueDictionary支持重复参数:
// PageModel中定义RouteValueDictionary [BindProperty(SupportsGet = true)] public RouteValueDictionary routeData { get; set; } public async Task OnGetAsync() { routeData = new RouteValueDictionary(); routeData.Add("SortOrder", CurrentSort); routeData.Add("SearchString", SearchString); if (Model.Colors != null && Model.Colors.Length > 0) { foreach (var color in Model.Colors) { if (!string.IsNullOrEmpty(color)) { // RouteValueDictionary允许重复键 routeData.Add("Colors", color); } } } }
视图中使用:
<a asp-page="./Index" asp-all-route-data="@Model.routeData"> @Html.DisplayNameFor(model => model.MyList[0].Colors) </a>
核心原因
Razor Pages的asp-route-*默认会对数组调用ToString()方法,因此生成了System.String[]的编码值;而Dictionary不支持重复键,导致之前的尝试只能传递单个Colors参数。
内容的提问来源于stack exchange,提问作者dave
相关产品推荐
相关产品推荐

