Как игнорировать / изменять параметр модели в ядре asp.net с помощью Swashbuckle.AspNetCore.Swagger

Мой проект ссылается на следующие пакеты;

  1. Swashbuckle.AspNetCore.Filters v6.0.0
  2. Swashbuckle.AspNetCore.Swagger v5.6.3
  3. Swashbuckle.AspNetCore.SwaggerGen v5.6.3
  4. Swashbuckle.AspNetCore.SwaggerNewtonSoft v5.6.3
  5. Microsoft.AspNetCore.OData v7.5.0

Вот в чем проблема:

У меня есть контроллер под названием TestController. В нем есть единственный метод [HttpGet] под названием Test.

Метод оформлен следующим образом;

[HttpGet]
[SwaggerOperation(OperationId = nameof(Test))]
public IActionResult Test([FromQuery] string id, [FromQuery] ODataQueryOptions<SearchOptions> oData)
{
    // ...
}

Поскольку я использую Swashbuckle, ожидаемые результаты должны заключаться в том, что существует метод get с именем Test с набором параметров запроса, возвращаемых в пользовательский интерфейс документации.

Однако вместо этого я вижу исключение. Исключение говорит;

Failed to generate Scheme for type - ODataQueryOptions<`T>. See inner exception

Проверка внутреннего исключения показывает, что swagger пытается создать внешне схему из множества типов системы (например, HttpContext, response, request и т. Д.).

Я считаю, что это происходит из-за того, что класс ODataQueryOption ‹` T ›имеет ряд контекстных свойств, которые помогают облегчить синтаксический анализ URI.

Подробнее об этом классе см. Здесь: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnet.odata.query.odataqueryoptions?view=odata-aspnetcore-7.0

Исключения и случайные поисковые запросы в Google привели меня к добавлению пользовательских IOperationFilter, ISchemeFilters и IParameterFilters (все они являются «фильтрами» конфигурации Swagger).

Я попытался полностью удалить операцию, установив для свойств значение null. Я попытался сделать то же самое с фильтрами схемы и параметров ... Все безуспешно. И никакой документации в помощь ...

Пример моих попыток:

class ParamFilter : IParameterFilter {
    public void Apply(OpenApiParameter parameter, ParameterFilterContext context) {
        parameter.Scheme = null;
        parameter.Reference = null;
    }
}

class SchemeFilter : ISchemeFilter {
    public void Apply(OpenApiScheme scheme, SchemeFilterContext context) {
        scheme.Items = null;
        scheme.Reference = null;
        scheme.Reference = null;
    }
}

// Note: this never gets hit by the debugger. App throws exception before invocation.
class OperationFilter : IOperationFilter {
    public void Apply(OpenApiOperation operation, OperationFilterContext context) {
        operation.Parameters.clear()
    }
}

Ничего не получилось. То же исключение.

На данный момент мой вопрос довольно прост;

Как удалить параметр ODataQueryOption из генерации документации Swagger?

РЕДАКТИРОВАТЬ: добавление сообщений об исключениях

  • Не удалось создать схему для типа - Microsoft.AspNet.OData.Query.ODataQueryOptions`1 [SearchOptions]. См. Внутреннее исключение
  • Не удалось создать схему для типа - Microsoft.AspNetCore.Http.HttpRequest. См. Внутреннее исключение
  • Не удалось создать схему для типа - Microsoft.AspNetCore.Http.HttpContext. См. Внутреннее исключение
  • Не удалось создать схему для типа - Microsoft.AspNetCore.Http.Authentication.AuthenticationManager. См. Внутреннее исключение
  • Не удалось загрузить тип Microsoft.AspNetCore.Http.Features.Authentication.AuthenticateContext из сборки Microsoft.AspNetCore.Http.Features, Version = 3.1.8.0, Culture = нейтральный, PublicKeyToken = adb9793829ddae60.

person Erik5388    schedule 29.09.2020    source источник


Ответы (1)


Это может хорошо работать в моем проекте:

Действие (обязательно удалите [FromQuery] на ODataQueryOptions):

[HttpGet]
[EnableQuery]
public IActionResult Test Get([FromQuery] string id, ODataQueryOptions<SearchOptions> ODataQueryOptions)
{
    //...
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddOData();
    services.AddControllers();

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    });

    SetOutputFormatters(services);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.EnableDependencyInjection();
        endpoints.Select().Filter().Expand().MaxTop(10);
        endpoints.MapODataRoute("odata", "odata", GetEdmModel());
    });

    app.UseSwagger();

    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });
}

IEdmModel GetEdmModel()
{
    var builder = new ODataConventionModelBuilder();
    builder.EntitySet<WeatherForecast>("WeatherForecast");
    return builder.GetEdmModel();
}

private static void SetOutputFormatters(IServiceCollection services)
{
    services.AddMvcCore(options =>
    {
        IEnumerable<ODataOutputFormatter> outputFormatters =
            options.OutputFormatters.OfType<ODataOutputFormatter>()
                .Where(foramtter => foramtter.SupportedMediaTypes.Count == 0);

        foreach (var outputFormatter in outputFormatters)
        {
            outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/odata"));
        }
    });
}
person Rena    schedule 30.09.2020