如果您只是显示简单的错误信息,您可以使用UseStatusCodePagesWithReExecute 和UseExceptionHandler 中间件,如下所示:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/errors/{0}");
app.UseExceptionHandler("/errors/500");
//...
}
错误控制器:
[ApiController]
[Route("[controller]")]
public class ErrorsController : ControllerBase
{
[Route("{code}")]
public IActionResult InternalError(int code)
{
return new ObjectResult(new ApiResponse(code));
}
}
自定义 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错误,你需要知道模型验证是在动作之前,所以你应该根据我之前的回答添加一个动作过滤器:
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:
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:
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