Reputation: 207
I have a model that's being used by one of the other models, that is being accepted as a parameter to one of my controllers. So as a result, this model is being displayed in Swagger UI. This model is a nullable type and is optional and I want to hide it from my documentation.
public class A
{
public string SomeProperty { get; set; }
public B? ClassB {get; set; }
}
public class B
{
public int SomeIntProperty { get; set; }
public bool SomeBooleanProperty { get; set; }
}
in the controller method:
public async Task<ActionResult<SomeType>> GetSomeType(A modelA, CancellationToken token)
As is, this endpoint will accept a JSON document like:
{
"SomeProperty": "SomeValue"
}
And won't need B to be present. So as a result, I want to hide B
from my Swagger schemas. How can I do that? I found some related questions/answers but all of them are about hiding properties, https://stackoverflow.com/a/48454933/16749442
Hiding all properties of a model results in empty model:
Upvotes: 2
Views: 4321
Reputation: 207
The only working and clean solution I found is, unfortunately, using reflection again.
SwaggerExcludeAttribute.cs
[AttributeUsage(AttributeTargets.Class)]
public class SwaggerExcludeAttribute : Attribute
{
}
SwaggerIgnoreModelFilter.cs
public class SwaggerIgnoreModelFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
// Get all models that are decorated with SwaggerExcludeAttribute
// This will only work for models that are under current Assembly
var excludedTypes = GetTypesWithHelpAttribute(Assembly.GetExecutingAssembly());
// Loop through them
foreach (var _type in excludedTypes)
{
// Check if that type exists in SchemaRepository
if (context.SchemaRepository.TryLookupByType(_type, out _))
{
// If the type exists in SchemaRepository, check if name exists in the dictionary
if (swaggerDoc.Components.Schemas.ContainsKey(_type.Name))
{
// Remove the schema
swaggerDoc.Components.Schemas.Remove(_type.Name);
}
}
}
}
// Get all types in assembly that contains SwaggerExcludeAttribute
public static IEnumerable<Type> GetTypesWithHelpAttribute(Assembly assembly)
{
return assembly.GetTypes().Where(type => type.GetCustomAttributes(typeof(SwaggerExcludeAttribute), true).Length > 0);
}
}
Startup.cs
services.AddSwaggerGen(c =>
{
.....
c.DocumentFilter<SwaggerIgnoreModelFilter>();
......
});
Upvotes: 5