There are several options to solve this:
- You can use the Controller feature provider to exclude
MetadataController
- You can use
Conventions
in ODataOptions
to remove MetadataRoutingConvention
.
- You can implement
DocumentFilter
to hide MetadataController
and related schemas from the Swagger
#2 is the simplest way:
services
.AddControllers()
.AddOData(opt =>
{
opt.Conventions.Remove(opt.Conventions.OfType<MetadataRoutingConvention>().First());
opt.AddRouteComponents("", GetEdmModel()).Select().Expand();
});
#3 If you just want to hide MetadataController
and related schemas from the 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);
}
}
}
}
Add it to the services.AddSwaggerGen
:
cfg.DocumentFilter<SwaggerODataControllerDocumentFilter>();
For option #1 you can do like:
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);
}
}
In the startup.cs
services.AddControllers()
.ConfigureApplicationPartManager(manager =>
{
manager.FeatureProviders.Remove(manager.FeatureProviders.OfType<ControllerFeatureProvider>().FirstOrDefault());
manager.FeatureProviders.Add(new RemoveMetadataControllerFeatureProvider());
}).AddOData(....)