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

基于.NET 8 Web API实现空路由参数自定义422错误响应问询

.NET 8 Web API路由参数为空时返回自定义422错误响应

问题说明

使用.NET 8默认ASP.NET Core Web API模板开发接口,路由路径结构无法修改(不能将路由参数转为查询参数)。当前接口定义了三个路由参数routeParam1、routeParam2、routeParam3,当请求中某路由参数为空(如路径中出现连续//)时,ASP.NET Core默认返回404 Not Found,需改为返回对应自定义内容的422 Unprocessable Entity响应。

解决方案

由于ASP.NET Core路由系统默认不匹配空路由参数的请求,因此需要先让请求能匹配到目标接口再校验参数;或通过中间件提前拦截请求并校验路由段。以下提供两种实现方式:

方式1:修改路由允许可选参数,在Action内直接校验

步骤1:更新路由与参数定义

将路由模板中的参数改为可选(添加?),并将路由参数类型改为可空字符串,确保空参数的请求能匹配到该Action:

[HttpGet]
[Route("{routeParam1?}/{routeParam2?}/path/{routeParam3?}", Name = "XYZ")]
[Produces("application/json")]
public async Task<IActionResult> XYZ(
                [FromRoute] string? routeParam1, 
                [FromRoute] string? routeParam2, 
                [FromRoute] string? routeParam3,
                [FromQuery] string queryParam1, 
                [FromQuery] string queryParam2, 
                CancellationToken cancellationToken)
{

步骤2:添加参数校验逻辑

在Action开头逐一校验路由参数是否为空,为空则返回对应的422响应:

// 校验routeParam1
if (string.IsNullOrWhiteSpace(routeParam1))
{
    return UnprocessableEntity(new { customCode = "1111", warning = "routeParam1 is required." });
}

// 校验routeParam2
if (string.IsNullOrWhiteSpace(routeParam2))
{
    return UnprocessableEntity(new { customCode = "2222", warning = "routeParam2 is required." });
}

// 校验routeParam3
if (string.IsNullOrWhiteSpace(routeParam3))
{
    return UnprocessableEntity(new { customCode = "3333", warning = "routeParam3 is required." });
}

// 原有业务逻辑
return new ObjectResult("ok") { StatusCode = 200 };

方式2:使用中间件拦截请求并校验路由段

若不想修改Action的参数定义,可通过自定义中间件提前解析请求路径,校验对应位置的路由段是否为空:

步骤1:实现自定义中间件

public class RouteParamValidationMiddleware
{
    private readonly RequestDelegate _next;

    public RouteParamValidationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        var pathSegments = context.Request.Path.Value?
            .Split('/', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>();

        // 匹配目标路由结构:{routeParam1}/{routeParam2}/path/{routeParam3}
        bool matchesTargetRoute = pathSegments.Length >= 3 
            && pathSegments[2].Equals("path", StringComparison.OrdinalIgnoreCase);

        if (matchesTargetRoute)
        {
            // 校验routeParam1(对应路径第1段)
            if (pathSegments.Length < 1 || string.IsNullOrWhiteSpace(pathSegments[0]))
            {
                await ReturnCustom422(context, "1111", "routeParam1 is required.");
                return;
            }

            // 校验routeParam2(对应路径第2段)
            if (pathSegments.Length < 2 || string.IsNullOrWhiteSpace(pathSegments[1]))
            {
                await ReturnCustom422(context, "2222", "routeParam2 is required.");
                return;
            }

            // 校验routeParam3(对应路径第4段)
            if (pathSegments.Length < 4 || string.IsNullOrWhiteSpace(pathSegments[3]))
            {
                await ReturnCustom422(context, "3333", "routeParam3 is required.");
                return;
            }
        }

        await _next(context);
    }

    private static async Task ReturnCustom422(HttpContext context, string customCode, string warning)
    {
        context.Response.StatusCode = StatusCodes.Status422UnprocessableEntity;
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsJsonAsync(new { customCode, warning });
    }
}

步骤2:注册中间件

在Program.cs中,将中间件注册到路由逻辑之后、端点映射之前:

var app = builder.Build();

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();

// 注册自定义路由参数校验中间件
app.UseMiddleware<RouteParamValidationMiddleware>();

app.MapControllers();
app.Run();

测试验证

分别发起以下请求,即可得到预期的422响应:

  • 请求1:/abc/xyz//routeParam2/path/routeParam3?queryParam1=p1&queryParam2=p2 → 返回customCode=1111的422响应
  • 请求2:/abc/xyz/routeParam1//path/routeParam3?queryParam1=p1&queryParam2=p2 → 返回customCode=2222的422响应
  • 请求3:/abc/xyz/routeParam1/routeParam2/path/?queryParam1=p1&queryParam2=p2 → 返回customCode=3333的422响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 02:08:11