.bet core 3.1 webapi的错误响应的全局自定义 [英] Global customization of error responses from .bet core 3.1 webapi
问题描述
我正在使用 app.UseExceptionHandler("/error");
自定义所有未处理异常的输出.
I'm using app.UseExceptionHandler("/error");
to customize the output of any unhandled exceptions.
但是,验证错误使用框架( ApiController
)并自动返回默认格式的错误.
However, validation errors use the framework (ApiController
) and automatically return a default formatted error.
我看到我可以使用 InvalidModelStateResponseFactory
覆盖它,但是有没有办法拥有一个全局位置来处理所有这些问题?
I see that I can overwrite this using InvalidModelStateResponseFactory
but is there a way to have one global location to handle all of these?
我知道一个代表500个响应,另一个代表400个响应,但我想尽可能合并.
I understand that one is for 500 responses and the other is 400 responses but I'd like to consolidate if possible.
推荐答案
如果只显示简单的错误消息,则可以使用 UseStatusCodePagesWithReExecute
和 UseExceptionHandler
中间件,如下所示:
If you just display simple error message,you could use UseStatusCodePagesWithReExecute
and UseExceptionHandler
middleware like below:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/errors/{0}");
app.UseExceptionHandler("/errors/500");
//...
}
ErrorsController:
ErrorsController:
[ApiController]
[Route("[controller]")]
public class ErrorsController : ControllerBase
{
[Route("{code}")]
public IActionResult InternalError(int code)
{
return new ObjectResult(new ApiResponse(code));
}
}
自定义ApiResponse:
Custom ApiResponse:
public class ApiResponse
{
public int StatusCode { get; }
public string Message { get; }
public ApiResponse(int statusCode, string message = null)
{
StatusCode = statusCode;
Message = message ?? GetDefaultMessageForStatusCode(statusCode);
}
private static string GetDefaultMessageForStatusCode(int statusCode)
{
switch (statusCode)
{
case 404:
return "Resource not found";
case 500:
return "An unhandled error occurred";
case 400:
return "Model error";
default:
return null;
}
}
}
如何测试:
1.对于500:
[HttpGet]
public IActionResult Get()
{
throw new Exception("adasd");
}
2.对于400:
[HttpPost]
public IActionResult Get(TestModel model)
{
if (!ModelState.IsValid)
{
return BadRequest();//can't pass the ModelState to it
}
return Ok();
}
如果要显示详细的ModelState错误,您需要知道模型验证是在执行操作之前,因此应基于我之前的回答添加操作过滤器:
If you want to display the detailed ModelState error,you need to know that model validation is before action,so you should add an action filter based on my previous answer:
public class ApiValidationFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(new ApiBadRequestResponse(context.ModelState));
}
}
}
自定义ApiBadRequestResponse:
Custom ApiBadRequestResponse:
public class ApiBadRequestResponse : ApiResponse
{
public IEnumerable<string> Errors { get; }
public ApiBadRequestResponse(ModelStateDictionary modelState)
: base(400)
{
if (modelState.IsValid)
{
throw new ArgumentException("ModelState must be invalid", nameof(modelState));
}
Errors = modelState.SelectMany(x => x.Value.Errors)
.Select(x => x.ErrorMessage).ToArray();
}
}
Startup.cs:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.Filters.Add(typeof(ApiValidationFilter));
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/errors/{0}");
app.UseExceptionHandler("/errors/500");
//...
}
结果:
参考:
https://www.devtrends.co.uk/blog/handling-errors-in-asp.net-core-web-api
这篇关于.bet core 3.1 webapi的错误响应的全局自定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!