Search code examples
c#openapinswag

Filtering/ignoring properties in NSwag at run time


In swashbuckler I have used this to trick to remove/ignore properties runtime:

services.AddSwaggerGen(c =>
{
    c.SchemaFilter<SwaggerExcludeSchemaFilter>();
}
// IServiceConfig is injected through IoC
public class SwaggerExcludeSchemaFilter(IServiceConfig config) : ISchemaFilter
{
    private int _ignoreLevel = config.IgnoreLevel;

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema.Properties == null || schema.Properties.Count == 0)
        {
            return;
        }

        var type = context.Type;
        var properties = type.GetProperties();

        foreach (var propertyInfo in properties)
        {
            if (propertyInfo.GetCustomAttribute<IgnoreFeatureAttribute>() is { } ignoreFeatureAttribute)
            {
                if (ignoreFeatureAttribute.Level < _ignoreLevel)
                {
                    if (schema.Properties.SingleOrDefault(x =>
                            x.Key.Equals(propertyInfo.Name, StringComparison.OrdinalIgnoreCase)) is var schemaProperty)
                    {
                        schema.Properties.Remove(schemaProperty.Key);
                    }
                }
            }
        }
    }
}

Is there a way to achive this when using NSwag?

I have tried playing with DocumentProcessors and SchemaProcessors but cannot find a way to ignore properties of a class.


Solution

  • I ended up doing this:

    public class ExcludeSchemaProcessor(IServiceConfig config) : ISchemaProcessor
    {
        private int _ignoreLevel = config.IgnoreLevel;
    
        public void Process(SchemaProcessorContext context)
        {
            var type = context.Type;
            var properties = type.GetProperties();
    
            foreach (var propertyInfo in properties)
            {
                if (propertyInfo.GetCustomAttribute<IgnoreFeatureAttribute>() is { } ignoreFeatureAttribute)
                {
                    if (ignoreFeatureAttribute.Level < _ignoreLevel)
                    {
                        var camelCasePropertyName = char.ToLowerInvariant(propertyInfo.Name[0]) + propertyInfo.Name.Substring(1);
                        context.Schema.Properties.Remove(camelCasePropertyName);
                    }
                }
            }
        }
    }
    
    services.AddOpenApiDocument(configure =>
    {
        configure.SchemaSettings.SchemaProcessors.Add(_ioc.Resolve<IServiceConfig>());
    });