C# API端点输入验证:如何用路由约束返回400错误?
如何让格式错误的GUID返回400 HTTP错误?
可以通过路由约束实现,但默认的guid路由约束在验证失败时不会直接返回400,而是会让请求匹配不到该端点,触发回退逻辑(比如返回404)。要达成返回400的需求,有两种可行方案:
方案一:自定义严格GUID路由约束+全局错误处理
- 创建自定义路由约束类,严格验证GUID格式:
public class StrictGuidRouteConstraint : IRouteConstraint { public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (!values.TryGetValue(routeKey, out var value) || value == null) return false; return Guid.TryParseExact(value.ToString(), "D", out _); // 验证标准连字符格式的GUID } }
- 在Program.cs中注册这个约束:
builder.Services.Configure<RouteOptions>(options => { options.ConstraintMap.Add("strictguid", typeof(StrictGuidRouteConstraint)); });
- 修改你的API路由,使用自定义约束:
[HttpGet("/api/{context:strictguid}")] public async Task<IActionResult> doSomething(Guid context) { // 业务逻辑代码 }
- 添加全局中间件,捕获路由匹配失败的情况并返回400:
app.Use(async (context, next) => { await next(); if (context.Response.StatusCode == StatusCodes.Status404NotFound) { var contextParam = context.Request.RouteValues["context"]; if (contextParam != null && !Guid.TryParse(contextParam.ToString(), out _)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; await context.Response.WriteAsJsonAsync(new { error = "无效的GUID格式" }); } } });
方案二:结合模型验证(更简单)
去掉路由上的guid约束,通过参数特性做格式验证,直接在方法内判断模型状态:
[HttpGet("/api/{context}")] public async Task<IActionResult> doSomething( [Required] [RegularExpression(@"^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$", ErrorMessage = "无效的GUID格式")] string context) { if (!ModelState.IsValid) { return BadRequest(ModelState); } Guid guidContext = Guid.Parse(context); // 业务逻辑代码 }
这种方式下,只要传入的context不符合GUID格式,ModelState会自动标记为无效,直接返回包含错误信息的400响应。
内容的提问来源于stack exchange,提问作者maksasj
相关产品推荐
相关产品推荐

