Blazor WASM无调试运行时带负整数参数的GET请求失效问题
负整数Query参数在Blazor WASM无调试模式下导致ModelState无效问题
我正在构建Blazor WASM应用,从自定义API端点(格式为/api/{controller})获取数据,支持通过ID筛选,部分ID为负整数。
调试运行时请求正常,日志如下:
Request finished HTTP/2 GET https://localhost:7133/api/plannedworkhours?From=2021-02-01&To=2021-02-14&SpotId=-1
但无调试运行时,ModelState无效,控制器抛出BadRequest异常,日志显示负号被转成了Unicode字符编码%E2%88%92:
Request finished HTTP/2 GET https://localhost:7133/api/plannedworkhours?From=2021-02-01&To=2021-02-14&SpotId=%E2%88%921
无负整数参数时请求正常,推测是URL编码/解码问题。
应用请求代码
var url = $"/api/plannedworkhours?From={startTime.ToString("yyyy-MM-dd")}&To={endTime.ToString("yyyy-MM-dd")}"; if (spotIds != null && spotIds.Length > 0) { url += $"&{string.Join("&", spotIds.Select(sid => $"SpotId={sid}"))}"; } return await client.GetFromJsonAsync<List<PlannedWorkHourModel>>(url);
API端点代码
public async Task<IActionResult> Get([FromQuery] PlannedWorkHoursQuery filter) { if (!ModelState.IsValid) { throw new BadRequestException(); // 无调试运行时触发此异常,调试时不会 } // ... 其他业务逻辑 }
查询参数类
public class PlannedWorkHoursQuery { public DateTime? From { get; set; } public DateTime? To { get; set; } public short[] SpotId { get; set; } }
问题原因与解决方案
问题根源是手动拼接URL时,负号被错误编码成了Unicode长破折号(−,对应编码%E2%88%92),而非ASCII标准短破折号(-,编码%2D)。ASP.NET Core无法将Unicode破折号解析为整数的负号,导致ModelState验证失败。
解决方法:不要手动拼接URL参数,改用官方工具类构建查询字符串,确保参数编码符合标准:
方案1:使用QueryHelpers构建URL
var queryParams = new Dictionary<string, string> { ["From"] = startTime.ToString("yyyy-MM-dd"), ["To"] = endTime.ToString("yyyy-MM-dd") }; if (spotIds != null && spotIds.Length > 0) { foreach (var sid in spotIds) { queryParams.Add("SpotId", sid.ToString()); } } var url = QueryHelpers.AddQueryString("/api/plannedworkhours", queryParams); return await client.GetFromJsonAsync<List<PlannedWorkHourModel>>(url);
方案2:使用HttpRequestMessage构建请求
var request = new HttpRequestMessage(HttpMethod.Get, "/api/plannedworkhours"); var query = new QueryString(); query = query.Add("From", startTime.ToString("yyyy-MM-dd")); query = query.Add("To", endTime.ToString("yyyy-MM-dd")); if (spotIds != null && spotIds.Length > 0) { foreach (var sid in spotIds) { query = query.Add("SpotId", sid.ToString()); } } request.RequestUri = new Uri(request.RequestUri + query.ToString()); var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync<List<PlannedWorkHourModel>>();
两种方式都会自动处理参数的URL编码,避免手动拼接导致的编码错误,确保负整数参数能被正确解析。
内容的提问来源于stack exchange,提问作者Tjulu
相关产品推荐
相关产品推荐

