【问题标题】:How to ignore/alter model parameter in asp.net core with Swashbuckle.AspNetCore.Swagger如何使用 Swashbuckle.AspNetCore.Swagger 在 asp.net 核心中忽略/更改模型参数
【发布时间】:2020-09-29 14:44:03
【问题描述】:

我的项目引用了以下包;

  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”的控制器。其中有一个名为 Test 的 [HttpGet] 方法。

方法修饰如下;

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

由于我使用的是 Swashbuckle,所以预期的结果应该是有一个名为 Test 的 get 方法,其中有一堆查询参数返回到文档 UI。

但是,我看到了一个异常。例外说;

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

检查内部异常表明,swagger 正在尝试构建看起来像是一堆系统类型(例如 HttpContext、响应、请求等)的方案。

我相信这种情况正在发生,因为 ODataQueryOption 类带有许多上下文属性以帮助促进 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 来完全删除操作。我已经尝试过使用 Scheme 和 Parameter 过滤器...都没有运气。并且没有文档可以提供帮助...

我的尝试示例:

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()
    }
}

没有任何效果。同样的例外。

此时我的问题相当简单;

如何从 swagger 文档生成中删除 ODataQueryOption 参数?

编辑:添加异常消息

  • 无法为类型 - 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,版本= 3.1.8.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'。

【问题讨论】:

    标签: asp.net-core-mvc swagger odata swashbuckle swashbuckle.aspnetcore


    【解决方案1】:

    它可以在我的项目中很好地工作:

    操作(请务必删除 ODataQueryOptions 上的 [FromQuery]):

    [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"));
            }
        });
    }
    

    【讨论】:

      【解决方案2】:

      尝试将ODataQueryOptions 的映射设置为options.MapType(typeof(ODataQueryOptions&lt;&gt;), () =&gt; new ());

      【讨论】:

        猜你喜欢
        • 2015-08-06
        • 2011-01-01
        • 2016-10-13
        • 2020-03-16
        • 2020-01-07
        • 1970-01-01
        • 2013-07-29
        • 2023-03-16
        • 2017-12-27
        相关资源
        最近更新 更多