如何自定义ASP.NET Core中UnprocessableEntityResult的响应内容?
在ASP.NET Core 9中返回带详细信息的422响应
你可以通过以下几种方式实现给422响应添加自定义错误信息或errors数组的需求:
1. 使用Problem()方法自定义状态码和错误信息
Problem()方法支持传入多个参数,包括状态码、标题、详情,甚至可以通过extensions参数添加自定义字段(比如errors数组),完全满足你的需求:
添加自定义详情和标题
return Problem( detail: "用户名已存在,请更换其他用户名", statusCode: StatusCodes.Status422UnprocessableEntity, title: "业务验证失败" );
返回的响应格式:
{ "type": "https://tools.ietf.org/html/rfc4918#section-11.2", "title": "业务验证失败", "status": 422, "detail": "用户名已存在,请更换其他用户名", "traceId": "00-xxxxxx-xxxxxx-00" }
添加errors数组(和默认400验证格式一致)
如果需要和模型验证的响应格式保持统一,可以用extensions参数注入errors字段:
return Problem( statusCode: StatusCodes.Status422UnprocessableEntity, title: "业务验证失败", extensions: new Dictionary<string, object?> { ["errors"] = new Dictionary<string, string[]> { ["Username"] = new[] { "用户名已存在,请更换其他用户名" } } } );
返回的响应格式:
{ "type": "https://tools.ietf.org/html/rfc4918#section-11.2", "title": "业务验证失败", "status": 422, "errors": { "Username": [ "用户名已存在,请更换其他用户名" ] }, "traceId": "00-xxxxxx-xxxxxx-00" }
2. 使用ValidationProblem()返回统一验证格式
ValidationProblem()原本用于模型验证场景,但也可以手动传入自定义错误字典,并指定422状态码,这样返回的格式和默认的400验证错误完全一致,客户端无需额外适配:
var validationErrors = new Dictionary<string, string[]> { ["Username"] = new[] { "用户名已存在,请更换其他用户名" } }; return ValidationProblem(validationErrors, statusCode: StatusCodes.Status422UnprocessableEntity);
返回的响应格式和你提供的400验证响应几乎一致,仅status字段为422:
{ "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1", "title": "One or more validation errors occurred.", "status": 422, "errors": { "Username": [ "用户名已存在,请更换其他用户名" ] }, "traceId": "00-xxxxxx-xxxxxx-00" }
如果需要自定义title,可以传入title参数:
return ValidationProblem( errors: validationErrors, statusCode: StatusCodes.Status422UnprocessableEntity, title: "业务规则验证失败" );
3. 手动构建ProblemDetails对象(完全自定义)
如果需要最高程度的自定义,可以直接实例化ProblemDetails对象,设置所有字段后通过ObjectResult返回:
var problemDetails = new ProblemDetails { Status = StatusCodes.Status422UnprocessableEntity, Title = "业务验证不通过", Detail = "请求格式合法,但违反业务规则", Type = "自定义的错误类型标识" // 可以替换成你自己的错误类型链接或标识 }; // 添加自定义errors字段 problemDetails.Extensions["errors"] = new Dictionary<string, string[]> { ["Username"] = new[] { "用户名已存在,请更换其他用户名" } }; // ASP.NET Core会自动添加traceId,无需手动设置 return new ObjectResult(problemDetails) { StatusCode = problemDetails.Status };
内容的提问来源于stack exchange,提问作者PaulH567
相关产品推荐
相关产品推荐

