ASP.NET Core 2.2 - Проблемные детали - PullRequest
0 голосов
/ 24 февраля 2019

Я недавно обновил свой проект ASP.NET Core с поддержкой Swagger до 2.2.Я заметил, что все мои сообщения об ошибках теперь отображаются с телом ответа ProblemDetails.

{
  "type": "string",
  "title": "string",
  "status": 0,
  "detail": "string",
  "instance": "string",
  "additionalProp1": {},
  "additionalProp2": {},
  "additionalProp3": {}
}

Согласно Microsoft это ожидается - и я доволен этим.

Однако по какой-то причине мой проект не возвращает их для некоторых кодов возврата по умолчанию, таких как 401. Это (как я полагаю) соответствующая часть моей конфигурации запуска.

    services
        .AddAuthentication(options => {
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(jwtOptions => {
            jwtOptions.Authority = jwtConfiguration.Authority;
            jwtOptions.TokenValidationParameters.ValidAudiences = jwtConfiguration.Audiences;
        });

    // Add framework services.
    services
        .AddMvcCore(options => {
            options.Filters.Add<OperationCancelledExceptionFilterAttribute>();
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
        .AddAuthorization()
        .AddApiExplorer()
        .AddJsonFormatters()
        .AddCors()
        .AddJsonOptions(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()));

    services.AddVersionedApiExplorer(
        options => {
            //The format of the version added to the route URL  
            options.GroupNameFormat = "'v'VVV";
            //Tells swagger to replace the version in the controller route  
            options.SubstituteApiVersionInUrl = true;
        });

    services.AddApiVersioning(option => {
        option.ReportApiVersions = true;
    });

    // Add data protection
    services.AddDataProtection();

    //Add swagger
    services.AddSwaggerGen(c => {
        c.SwaggerDoc("v1", new Info { Version = "1.0", ...});
        c.SwaggerDoc("v2", new Info { Version = "2.0", ...});
        c.AddSecurityDefinition("Bearer", ...});
        c.AddSecurityRequirement(...);
        c.DescribeAllEnumsAsStrings();
        c.EnableAnnotations();
    });

    //Add documentation for end point
    services.AddSwaggerGen(...});

При такой настройке любой неавторизованный запрос заканчивается 401, но без каких-либо проблем прилагается.Это не то, что, как я понял, должно произойти, и я не могу понять, какой переключатель мне нужно нажать, чтобы это произошло.

1 Ответ

0 голосов
/ 24 июня 2019

По умолчанию только для 400 BadRequests, когда проверка модели не удалась.Это делается с помощью фильтра, который автоматически вставляется при добавлении атрибута ApiController в ваш контроллер.На это поведение может влиять ApiBehaviorOptions в случае фильтра, в частности InvalidModelStateResponseFactory.

Другие возникающие исключения также не сопоставляются с деталями проблемы, для этого вам необходимо написать собственное промежуточное программное обеспечение.Что-то вроде следующего:

public class ExceptionMiddleware
{
    private readonly IActionResultExecutor<ObjectResult> _executor;

    public ExceptionMiddleware(RequestDelegate next, IActionResultExecutor<ObjectResult> executor)
    {
        _next = next;
        _executor = executor;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        } 
        catch(Exception ex) 
        {
            await ExecuteProblemDetailsResultAsync();
            return;
        }
    }

    private Task ExecuteProblemDetailsResultAsync(HttpContext context, Exception ex)
    {
        var routeData = context.GetRouteData();
        var actionContext = new ActionContext(context, routeData, new ActionDescriptor());

        var problemDetails = ex.ToProblemDetails();
        return _executor.ExecuteAsync(actionContext, new ObjectResult(problemDetails));
    }
}

Но это все равно не вернет 401 Несанкционированный как Сведения о проблеме, для этого вам нужно перехватить HttpResponse в вашем промежуточном программном обеспечении и также преобразовать его в Детали проблемы.

Но поскольку у меня были те же проблемы, и я хотел, чтобы все исключения из моих API-интерфейсов возвращались в качестве сведений о проблеме, я создал пакет NuGet, который называется HttpExceptions, который делает это для вас :) Посмотрите, и, возможно, это тоже хорошорешение для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...