Есть замечательная статья, подробно объясняющая вашу проблему - Использование промежуточного программного обеспечения для перехвата исключений в Asp.Net Core .
Что вам нужно помнить о промежуточном программном обеспечении, это следующее:
Промежуточное программное обеспечение добавляется в ваше приложение во время запуска, как вы видели выше.Порядок, в котором вы вызываете методы Use ..., имеет значение!Промежуточное ПО «протекает через воду» до тех пор, пока не будет выполнено либо все, либо одна из них не остановится.
Первым, что передается на ваше промежуточное ПО, является делегат запроса.Это делегат, который берет текущий объект HttpContext и выполняет его.Ваше промежуточное ПО сохраняет его при создании и использует его на шаге Invoke ().Invoke () - то, где работа сделана.Все, что вы хотите сделать с запросом / ответом как часть вашего промежуточного программного обеспечения, делается здесь.Некоторым другим использованием промежуточного программного обеспечения может быть авторизация запроса на основе заголовка или внедрение заголовка в запрос или ответ
Итак, что вы делаете, вы пишете новый тип исключения и обработчик промежуточного программного обеспечениячтобы перехватить ваше исключение:
Новый класс типов исключений:
public class HttpStatusCodeException : Exception
{
public int StatusCode { get; set; }
public string ContentType { get; set; } = @"text/plain";
public HttpStatusCodeException(int statusCode)
{
this.StatusCode = statusCode;
}
public HttpStatusCodeException(int statusCode, string message) : base(message)
{
this.StatusCode = statusCode;
}
public HttpStatusCodeException(int statusCode, Exception inner) : this(statusCode, inner.ToString()) { }
public HttpStatusCodeException(int statusCode, JObject errorObject) : this(statusCode, errorObject.ToString())
{
this.ContentType = @"application/json";
}
}
И обработчик промежуточного программного обеспечения:
public class HttpStatusCodeExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<HttpStatusCodeExceptionMiddleware> _logger;
public HttpStatusCodeExceptionMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_logger = loggerFactory?.CreateLogger<HttpStatusCodeExceptionMiddleware>() ?? throw new ArgumentNullException(nameof(loggerFactory));
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (HttpStatusCodeException ex)
{
if (context.Response.HasStarted)
{
_logger.LogWarning("The response has already started, the http status code middleware will not be executed.");
throw;
}
context.Response.Clear();
context.Response.StatusCode = ex.StatusCode;
context.Response.ContentType = ex.ContentType;
await context.Response.WriteAsync(ex.Message);
return;
}
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class HttpStatusCodeExceptionMiddlewareExtensions
{
public static IApplicationBuilder UseHttpStatusCodeExceptionMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<HttpStatusCodeExceptionMiddleware>();
}
}
Затем используйте ваше новое промежуточное ПО:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseHttpStatusCodeExceptionMiddleware();
}
else
{
app.UseHttpStatusCodeExceptionMiddleware();
app.UseExceptionHandler();
}
app.UseStaticFiles();
app.UseMvc();
}
Конечное использование простое:
throw new HttpStatusCodeException(StatusCodes.Status400BadRequest, @"You sent bad stuff");