У меня есть несколько контроллеров .Net, которые выглядят так:
[HttpGet("{id}")]
public async Task<ActionResult<Int32>> GetById(Int32 id)
{
id = FormatId(id);
return lookupId(id);
}
Предположим, у меня есть десятки этих конечных точек на нескольких контроллерах, и некоторые из них требуют, чтобы идентификатор был отформатирован определенным образом, например целое число, дополненное до 5 цифр, поэтому FormatId дополняет его для меня, и если он больше 5 цифр, он выдает исключение BadHttpRequestException. .
Теперь вместо того, чтобы засорять все конечные точки, связанные с идентификатором,:
try/catch { return BadRequest() }
Могу ли я каким-либо образом прикрепить общий обработчик исключений к любым/всем конечным точкам/контроллерам?
По сути, я просто хочу сделать что-то вроде:
Controller.OnException(Exception e)
{
if (e.Type == BadHttpRequestException) // Ignore invalid C# syntax, just pseudocode
{
return BadRequest(e.Message);
}
}
Я предполагаю, что это будет поддерживаемый способ, или могу ли я иметь доступ к уровню над конечной точкой контроллера, чтобы я мог сам его поймать и сделать что-то вроде:
public MyWrapperEndpoint(T endpoint)
{
try {
endpoint(); // call whatever endpoint was requested (GetById)
} catch (BadHttpRequestException e) {
return BadRequest(e.Message); // Return the common exception message
}
}
По сути, мой вопрос сводится к тому, что если мои нижние уровни выдают исключение BadHttpRequestException (или любое другое исключение, которое, как я знаю, я явно выбрасываю), как я могу легко заставить все конечные точки моего контроллера перехватывать это исключение и возвращать объект BadRequest?
Вместо 400 Bad Request я бы поместил пользовательское ограничение маршрута в заполнитель id и позволил ему возвращать 404 Not Found, поскольку он никогда не будет/не должен находить что-то, что не соответствует формату.
Это называется глобальной обработкой исключений путем реализации промежуточного программного обеспечения в .Net Использование промежуточного программного обеспечения для перехвата исключений в Asp.Net Core Обработка исключений веб-API ASP.NET Core





Я думаю, что промежуточное программное обеспечение, перехватывающее исключения обработки, должно соответствовать вашим потребностям:
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next;
public ExceptionHandlingMiddleware(
RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (BadHttpRequestException ex)
{
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
await httpContext.Response.WriteAsJsonAsync(new
{
message = ex.Message,
});
}
}
}
А затем вы добавили его в качестве промежуточного программного обеспечения в свой стартап или программу в зависимости от того, где вы создаете свое приложение:
builder.UseMiddleware<ExceptionHandlingMiddleware>();
Промежуточное программное обеспечение позволяет контроллеру вызывать логику сервиса, логика сервиса выдает исключение, и если вы не перехватите исключение на уровне контроллера, промежуточное программное обеспечение перехватит его. Плюс этого подхода в том, что вы по-прежнему можете перехватывать исключения в своих контроллерах и возвращать разные коды состояния или поведения. Промежуточное программное обеспечение является спасателем всех контроллеров конечных точек без попыток и перехвата. Обратите внимание, что я добавил только ваше исключение BadHttpRequestException, но вы можете продолжить перехват всех типов и общего исключения.