RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.67k stars 1.23k forks source link

Ignoring properties in generated json dynamicaly #4741

Open pgpaccuratech opened 6 months ago

pgpaccuratech commented 6 months ago

Very similar to this (outdated): https://github.com/RicoSuter/NSwag/issues/1267

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 anyway to remove properties from the schema runtime, when using NSwag?

RicoSuter commented 6 months ago

You can implement a schema processor https://github.com/RicoSuter/NJsonSchema/wiki/Schema-Processors and modify a schema after it's creation...

pgpaccuratech commented 6 months ago

Thank you so much. For others that may come accros this, this how I did:

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);
                }
            }
        }
    }
}