Skip to content

[REQ] Could an option be added to the C# generator to support Enums as string where the values are actually bit flags. #17121

@stevelknievel76

Description

@stevelknievel76

Is your feature request related to a problem? Please describe.

I can't satisfactorily support enums that represent bit flags in sdks generated by openapi-generator

Describe the solution you'd like

I don't know whether this has been requested before so apologies if it has and I didn't spot it.

I wondered if it would be possible to support enums as string where the values represent bit flags.

In my API there are some properties which are enums which are decorated with the [Flags] annotation. For example:

[Flags]
public enum Weather
{
    Sun = 1,
    Rain = 2,
    Wind = 4,
    Lightning = 8
}

In my Startup.cs I have:

        services.AddControllers()
            .AddJsonOptions(opt =>
            {
                opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
            }

This adds the following to the swagger spec.

  "Weather": {
      "enum": [
        "Sun",
        "Rain",
        "Wind",
        "Lightning"
      ],
      "type": "string"
    },

As per above, the swagger spec doesn't include any numeric values, so the generator can't know that this enum represents bit flags. In the openapi-generator generated code you get:

    public enum Weather
    {
        /// <summary>
        /// Enum Sun for value: Sun
        /// </summary>
        [EnumMember(Value = "Sun")]
        Sun = 1,

        /// <summary>
        /// Enum Rain for value: Rain
        /// </summary>
        [EnumMember(Value = "Rain")]
        Rain = 2,

        /// <summary>
        /// Enum Wind for value: Wind
        /// </summary>
        [EnumMember(Value = "Wind")]
        Wind = 3

        /// <summary>
        /// Enum Lightning for value: Lightning
        /// </summary>
        [EnumMember(Value = "Lightning")]
        Lightning = 4
    }

The API accepts multiple enum values in the input and JsonStringEnumConverter will convert values from/to the correct combination of flags during serialization/deserialization. For example:

"weatherToday": "Sun,Wind,Lightning"

This would arrive in my controller as:

Sun | Wind | Lightning = 13

It would be nice if the cli supported an option, for example, --flag-enums "<comma separated list of all enums which represent bit flags>", and apply special logic for this set of enums:

  • The auto-generated enum would be assigned the [Flags] annotation.
  • Bit flag numbers 1, 2, 4, 8, 16, 32, etc would be assigned to each value (NB. for this to work they would not need to match those used in the API which is good since the swagger spec doesn't include them), allowing the client code to build up combinations of flags.

So in my example above the auto-generated code would become:

    [Flags]
    public enum Weather
    {
        /// <summary>
        /// Enum Sun for value: Sun
        /// </summary>
        [EnumMember(Value = "Sun")]
        Sun = 1 << 0,

        /// <summary>
        /// Enum Rain for value: Rain
        /// </summary>
        [EnumMember(Value = "Rain")]
        Rain = 1 << 1,

        /// <summary>
        /// Enum Wind for value: Wind
        /// </summary>
        [EnumMember(Value = "Wind")]
        Wind = 1 << 2,

        /// <summary>
        /// Enum Lightning for value: Lightning
        /// </summary>
        [EnumMember(Value = "Lightning")]
        Lightning = 1 << 4
    }

There is just one gotcha. This solution would not work where the enum in the API includes values which are built up from combinations of bit flags and/or where there is a value defined for 0 (ie None), but I'd argue that this is an acceptable limitation that should be clearly documented.

Describe alternatives you've considered

The workaround is to change the spec of my APIs to accept an array of flags, then bitwise OR them in my controller.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions