Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: const fields #2609

Closed
tomasbruckner opened this issue Feb 9, 2023 · 1 comment
Closed

Feature Request: const fields #2609

tomasbruckner opened this issue Feb 9, 2023 · 1 comment

Comments

@tomasbruckner
Copy link

tomasbruckner commented Feb 9, 2023

If you have a const field

public const string Bar = "foo";

It would be great if it generated a not nullable enum with only one value ("foo"). Now it is ignored.

When OpenAPI.NET starts supporting version 3.1, it could be generated as a constant value OAI/OpenAPI-Specification#1313

Also if there is some workaround on how to rewrite the string field/property to an enum with one value now, it would be appreciated if you shared this knowledge👍

@tomasbruckner
Copy link
Author

tomasbruckner commented Feb 27, 2023

Workaround is to create an attribute. Something like

[AttributeUsage(AttributeTargets.Property)]
public class SwaggerConstTypeAttribute : Attribute
{
    public SwaggerConstTypeAttribute(string enumValue)
    {
        Value = enumValue;
    }

    public string Value { get; }
}

Annotate your desired class

public class Foo
{
    [SwaggerConstType("const-value")]
    public string Type { get; set; }
}

Create SchemaFilter

public class SwaggerConstTypeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {
        foreach (var property in context.Type.GetProperties())
        {
            var schemaPropertyName = PropertyName(property);
            // This check ensures that properties that are not in the schema are not added.
            // This includes properties marked with [IgnoreDataMember] or [JsonIgnore].
            if (model.Properties?.ContainsKey(schemaPropertyName) != true)
            {
                continue;
            }

            if (property.CustomAttributes.Any(attr => attr.AttributeType == typeof(SwaggerConstTypeAttribute)))
            {
                var constAttribute = property.GetCustomAttribute<SwaggerConstTypeAttribute>();
                model.Properties[schemaPropertyName].Enum = new List<IOpenApiAny>
                {
                    new OpenApiString(constAttribute.Value)
                };
                model.Properties[schemaPropertyName].Nullable = false;
                continue;
            }
        }
    }

   // if you are using camelCasePropertyName
    private static string PropertyName(MemberInfo property)
    {
        return new CamelCasePropertyNamesContractResolver().GetResolvedPropertyName(property.Name);
    }
}

And register the filter in

services.AddSwaggerGen(
    c =>
    {
        ...
        c.SchemaFilter<SwaggerConstTypeFilter>();
        ...
    }
);

@martincostello martincostello closed this as not planned Won't fix, can't repro, duplicate, stale Apr 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants