Created
January 31, 2025 10:55
-
-
Save jkone27/6e2503deb46912790914305bf6657768 to your computer and use it in GitHub Desktop.
Required Schema filter to remove nullable properties from required list in Swagger generation in aspnetcore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace App.Swagger.Filters; | |
using System; | |
using System.Linq; | |
using System.Reflection; | |
using Microsoft.OpenApi.Models; | |
using Swashbuckle.AspNetCore.SwaggerGen; | |
/* | |
services.AddSwaggerGen(c => | |
{ | |
c.SupportNonNullableReferenceTypes(); | |
// this filter is needed by some typescript generators that use the required list only (not nullable prop) | |
c.SchemaFilter<SwaggerRequiredSchemaFilter>(); | |
}); | |
*/ | |
/// <summary> | |
/// Adds required list of properties in schema objects for openapi generation | |
/// </summary> | |
public class SwaggerRequiredSchemaFilter : ISchemaFilter | |
{ | |
public void Apply(OpenApiSchema schema, SchemaFilterContext context) | |
{ | |
if (schema.Properties == null) | |
{ | |
return; | |
} | |
foreach (var schemProp in schema.Properties) | |
{ | |
var propertyInfo = context.Type.GetProperty(schemProp.Key); | |
if (propertyInfo == null) | |
{ | |
continue; | |
} | |
// Check if the property is explicitly marked as nullable | |
bool isNullable = IsPropertyNullable(context, propertyInfo); | |
// Only mark as required if it's NOT nullable | |
if (!isNullable && !schema.Required.Contains(schemProp.Key)) | |
{ | |
schema.Required.Add(schemProp.Key); | |
} | |
else | |
{ | |
if (schema.Required.Contains(schemProp.Key)) | |
{ | |
schema.Required.Remove(schemProp.Key); | |
} | |
} | |
} | |
} | |
private static readonly NullabilityInfoContext nullabilityContext = new NullabilityInfoContext(); | |
private static bool IsPropertyNullable(SchemaFilterContext context, PropertyInfo propertyInfo) | |
{ | |
// nullable value type (e.g., int?, DateTime?) | |
if (Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null) | |
{ | |
return true; | |
} | |
// nullable reference type (Type?) by inspecting metadata | |
if (!propertyInfo.PropertyType.IsValueType) | |
{ | |
var nullabilityInfo = nullabilityContext.Create(propertyInfo); | |
if (nullabilityInfo.WriteState is NullabilityState.Nullable) | |
{ | |
return true; | |
} | |
} | |
// Otherwise, assume it's required (non-nullable) | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment