.NET 10 解决 URL 过长:实操新 QUERY 方法
当请求行超过 8KB 时,Kestrel 会直接甩给你一个 414 Request-URI Too Long。在做产品搜索过滤时,如果用户保存了包含几百个 SKU 的过滤集,URL 长度很容易触顶。传统的方案要么强行用 POST(破坏语义且影响缓存),要么把参数塞进 Header(太 hack),直到 .NET 10 正式引入了 RFC 10008 定义的
下一篇
JS实现CNPJ字母格式校验:别让旧正则搞崩你的系统 →
QUERY 方法。简单来说,QUERY 就是一个“带 Body 的 GET”,它既保证了幂等性,又能承载大数据量的查询条件。
在 ASP.NET Core 10 中部署
目前 .NET 10 提供了底层支持,但还没给 [HttpQuery] 这种语法糖,所以得通过 MapMethods 来手动挂载。
app.MapMethods("/products/search", [HttpMethods.Query], async (HttpContext ctx) =>
{
// 从 Body 中反序列化过滤条件
var filter = await JsonSerializer.DeserializeAsync(ctx.Request.Body);
var result = RunSearch(filter!.Skus, filter.MaxPrice);
// 根据规范,可以用 Content-Location 指向结果页
ctx.Response.Headers.ContentLocation = $"/products/search-results/{result.Execution}";
return Results.Ok(result);
});客户端调用也非常直接,直接使用 HttpMethod.Query 即可:
using var req = new HttpRequestMessage(HttpMethod.Query, "/products/search");
req.Content = new StringContent(json, Encoding.UTF8, "application/json");
using var resp = await http.SendAsync(req);避坑指南:必须手动校验 Content-Type
这里有个实操细节:RFC 规范要求如果 Content-Type 缺失或不匹配,服务器必须报错。但 ASP.NET Core 的 MapMethods 处理器不会自动帮你做这件事,需要手动加上校验逻辑,否则不符合规范:
if (string.IsNullOrEmpty(ctx.Request.ContentType))
return Results.Problem("QUERY requires a Content-Type.", statusCode: 400);
if (!ctx.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
return Results.StatusCode(StatusCodes.Status415UnsupportedMediaType);实测下来,用 QUERY 替代 GET 传递 65KB 的过滤参数毫无压力,彻底解决了 URL 长度限制导致的 414 报错问题。