#c# #asp.net-core #asp.net-web-api #graphql #asp.net-core-middleware
Вопрос:
В версиях до .net6 я обычно добавлял an ErrorHandlerMiddleware
в конвейер, чтобы централизовать необходимость возврата типов ошибок в приложении с различными кодами состояния. примером может служить что-то точно такое:
public class ErrorHandlerMiddleware { private readonly RequestDelegate _next; public ErrorHandlerMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception error) { string responseMessage = error.Message; string exceptionMessage; object ResponseObject; var response = context.Response; response.ContentType = "application/json"; switch (error) { case ApplicationBadRequestException e: if (e.metaData is { }) ResponseObject = new { responseMessage, e.metaData }; else ResponseObject = new { responseMessage }; response.StatusCode = StatusCodes.Status400BadRequest; break; case ApplicationNotFoundException e: if (e.metaData is { }) ResponseObject = new { responseMessage, e.metaData }; else ResponseObject = new { responseMessage }; response.StatusCode = StatusCodes.Status404NotFound; break; case ApplicationUnAuthorizedException e: responseMessage = "You are not authorized to perform this operation."; ResponseObject = new { responseMessage }; response.StatusCode = StatusCodes.Status401Unauthorized; break; default: responseMessage = "An error has occurred...Please try again later."; exceptionMessage = getExMessage(error); ResponseObject = new { responseMessage, exceptionMessage }; response.StatusCode = (int)HttpStatusCode.InternalServerError; break; } var result = JsonSerializer.Serialize(ResponseObject); await response.WriteAsync(result); } } }
Затем на любом контроллере в моем приложении, когда мне нужно вернуть определенный код ошибки в ответе — например, 400 BadRequest — я делаю это так
throw new ApplicationBadRequestException("this is the error message");
Это приводит к отмене конвейера промежуточного программного обеспечения, и это исключение извлекается внутри ErrorhandlerMiddleware
.
Теперь я пытаюсь использовать GraphQL в.net6, когда я делаю это, я вижу, что конвейер промежуточного программного обеспечения НЕ отменен и ErrorHandlerMiddleware
класс не вызывается. почему это происходит? РЕДАКТИРОВАТЬ: Я попробовал тот же сценарий с API-интерфейсами rest, и код работает отлично, похоже, что проблема возникает из-за наличия GraphQL
конфигурации.
это мой файл Program.cs
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var connectionString = builder.Configuration["ConnectionStrings:DBConnectionString"]; builder.Services.AddDbContextFactorylt;DBEntitiesgt;(options =gt; options.UseSqlServer(connectionString, x =gt; x.UseNetTopologySuite())); builder.Services.AddScopedlt;DBEntitiesgt;(options =gt; options.GetRequiredServicelt;IDbContextFactorylt;DBEntitiesgt;gt;().CreateDbContext()); builder.Services.AddGraphQLServer().AddQueryTypelt;Querygt;().AddMutationTypelt;Mutationgt;() .AddProjections().AddFiltering().AddSorting(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseMiddlewarelt;ErrorHandlerMiddlewaregt;(); app.MapGraphQL("/graphql"); app.Run();
Комментарии:
1. Что происходит, когда вы переступаете
await _next(context)
через себяErrorHandlerMiddleware
? Я предполагаю, что в asp.net основной конвейер mvc, который обрабатывает исключение и предотвращает его попадание в ваше промежуточное программное обеспечение.2. @SanderDeclerck, Нет, в моем приложении нет таких фильтров, на самом деле я реализовал функцию, которая напрямую создает исключение, просто чтобы проверить этот сценарий. Когда я переступаю через него, он поражается только при запуске приложения, а не после того, как возникает исключение, и это именно моя проблема.
3. Как было отредактировано, я попытался использовать ту же структуру со стандартным приложением Rest в .net6, и все работало так, как ожидалось.