【问题标题】:How to hide OData Metadata Controller in Swagger?如何在 Swagger 中隐藏 OData 元数据控制器?
【发布时间】:2022-01-25 01:39:40
【问题描述】:

将我的项目更新到 .NET6 并将 OData 更新到 8.0.4 后,出现了具有这些端点的新元数据控制器:

我想以某种方式禁用它或将其从我的服务中删除。

OData服务添加代码:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddControllers(mvcOptions => mvcOptions.EnableEndpointRouting = false)
        .AddOData(opt => opt.AddRouteComponents("", GetEdmModel()).Select().Expand());
}

版本:

  • .NET6
  • ASP.NET Core 6
  • OData 8.0.4

【问题讨论】:

    标签: c# .net asp.net-core odata .net-6.0


    【解决方案1】:

    有几种方法可以解决这个问题:

    1. 您可以使用the Controller feature provider 排除MetadataController
    2. 您可以在ODataOptions 中使用Conventions 删除MetadataRoutingConvention
    3. 您可以实现 DocumentFilter 以从 Swagger 中隐藏 MetadataController 和相关架构

    #2 是最简单的方法:

    services
        .AddControllers()
        .AddOData(opt =>
       {
             opt.Conventions.Remove(opt.Conventions.OfType<MetadataRoutingConvention>().First());
             opt.AddRouteComponents("", GetEdmModel()).Select().Expand();
        });
    

    #3 如果您只想对 Swagger 隐藏 MetadataController 和相关架构:

    public class SwaggerODataControllerDocumentFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            // remove controller
            foreach (ApiDescription apiDescription in context.ApiDescriptions)
            {
                var actionDescriptor = (ControllerActionDescriptor)apiDescription.ActionDescriptor;
                if (actionDescriptor.ControllerName == "Metadata")
                {
                    swaggerDoc.Paths.Remove($"/{apiDescription.RelativePath}");
                }
            }
    
            // remove schemas
            foreach ((string key, _) in swaggerDoc.Components.Schemas)
            {
                if (key.Contains("Edm") || key.Contains("OData"))
                {
                    swaggerDoc.Components.Schemas.Remove(key);
                }
            }
        }
    }
    

    添加到services.AddSwaggerGen:

    cfg.DocumentFilter<SwaggerODataControllerDocumentFilter>();
    

    对于选项 #1,您可以这样做:

    public class RemoveMetadataControllerFeatureProvider : ControllerFeatureProvider
        {
            protected override bool IsController(TypeInfo typeInfo)
            {
                if (typeInfo.FullName == "Microsoft.AspNetCore.OData.Routing.Controllers.MetadataController")
                {
                    // or just compare the name
                    return false;
                }
    
                return base.IsController(typeInfo);
            }
        }
    

    在startup.cs中

    services.AddControllers()
        .ConfigureApplicationPartManager(manager =>
         {
           manager.FeatureProviders.Remove(manager.FeatureProviders.OfType<ControllerFeatureProvider>().FirstOrDefault());
              manager.FeatureProviders.Add(new RemoveMetadataControllerFeatureProvider());
         }).AddOData(....)
    

    【讨论】:

      【解决方案2】:

      我最近遇到了类似的问题。我得到了解决方案

      • 从启动文件中删除 odata 服务注入(因为如果我尝试从启动文件中注入 odata,swagger 会自动添加元数据类)
      • 将 OData 从 8.0.4 降级到 8.0.0
      • 并在控制器内部实现 ODataQueryOptions 而不是 EnableQuery actionfilter
      • 在控制器中使用 ODataBuilder/OdataModelBuilder 而不是启动。就我而言,它是 ODataBuilder

      【讨论】:

      • 谢谢,会检查的。我会给你一个答案。
      • 你是在 Controller 中注入 OData 吗?我也已经实现了属性。有问题添加。
      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 2018-12-01
      • 1970-01-01
      相关资源
      最近更新 更多