如何在 Swagger 中隐藏 OData 元数据控制器?

kan*_*ls_ 5 .net c# odata asp.net-core .net-6.0

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

在此输入图像描述

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

添加OData服务的代码:

启动.cs

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

版本:

  • .NET6
  • ASP.NET 核心 6
  • 奥数据8.0.4

Rom*_*syk 8

有几种选择可以解决这个问题:

  1. 您可以使用控制器功能提供程序来排除MetadataController
  2. 您可以使用ConventionsinODataOptions来删除MetadataRoutingConvention.
  3. 您可以从 Swagger 中实现DocumentFilter隐藏和相关架构MetadataController

#2是最简单的方法:

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

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

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将其添加到services.AddSwaggerGen

cfg.DocumentFilter<SwaggerODataControllerDocumentFilter>();
Run Code Online (Sandbox Code Playgroud)

对于选项#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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在startup.cs中

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