I'm using AddSwaggerGen
in an ASP.NET Core project. I wrote an ISchemaFilter
to change the property values that the Swagger UI uses in its example JSON. I used this approach because the filter instantiates my model types to get the default values for the properties. That part works and isn't shown here.
The filter also changes the example value for Nullable<T>
properties to null
. This works for most types, but fails for enum properties.
public class SwaggerPropertyValueFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type.Namespace == "MyAPI.Services.Models" && context.Type.GetConstructor(Type.EmptyTypes) != null)
{
var schemaProps = schema.Properties.OrderBy(o => o.Key).Select(o => o.Value);
var modelProps = context.Type.GetProperties().OrderBy(o => o.Name);
var props = schemaProps.Zip(modelProps, (schema, model) => new { Schema = schema, Model = model } );
foreach(var prop in props)
{
var type = Nullable.GetUnderlyingType(prop.Model.PropertyType);
if (type != null)
{
prop.Schema.Example = new OpenApiNull();
continue;
}
}
}
}
}
I noticed that OpenApiSchema.Nullable
is false for nullable enum properties, but setting it to true also doesn't make any difference.
This is caused by enums being treated as reference types in the OpenAPI schema. (Incidentally, strings aren't.) There are two options/workarounds:
SwaggerGenOptions.UseAllOfToExtendReferenceSchemas()
to make the Swagger UI allow metadata on properties of reference types. With this option, the schema filter's Apply
is sometimes called with a context.Type
that has properties and an OpenApiSchema
that does not, so you have to check for that.SwaggerGenOptions.UseInlineDefinitionsForEnums()
to inline enum properties. With this option, the enum is no longer a type in your schema.