OpenAPITools / OpenAPITools/openapi-generator
[REQ][C#] Support Case-Insensitive String Enums
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Is your feature request related to a problem? Please describe.
The Java client offers a useCaseInsensitiveEnums flag in the configuration to support case-insensitive string enums. It would be great if the C# SDK offered the same - it looks like this is requested for other generators in ##16634 and #17398
Describe the solution you'd like
A config option for allowing case-insensitive string enums. Our API sends a webhook that we have defined as an enum in our OpenAPI spec with the values in and out. When attempting to serialize to a model generated via the project - I get this error
Microsoft.AspNetCore.Http.BadHttpRequestException: Failed to read parameter "List<MessageDeliveredCallback> callbackData" from the request body as JSON.
---> System.Text.Json.JsonException: The JSON value could not be converted to Bandwidth.Standard.Model.MessageDeliveredCallbackMessage. Path: $[0].message.direction | LineNumber: 22 | BytePositionInLine: 23.
at System.Text.Json.ThrowHelper.ThrowJsonException(String message)
at System.Text.Json.Serialization.Converters.EnumConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.TryReadAsObject(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, Object& value)
.....
This is the generated model definition
[JsonConverter(typeof(StringEnumConverter))]
public enum MessageDirectionEnum
{
/// <summary>
/// Enum In for value: in
/// </summary>
[EnumMember(Value = "in")]
In = 1,
/// <summary>
/// Enum Out for value: out
/// </summary>
[EnumMember(Value = "out")]
Out = 2
}
From what I can tell - dotnet doesnt have any built in support for this so we would need a custom CaseInsensitiveEnumConverter<T> class that looks something like
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
public class CaseInsensitiveEnumConverter<T> : JsonConverter<T> where T : struct, Enum
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if (Enum.TryParse(value, ignoreCase: true, out T result))
{
return result;
}
throw new JsonException($"Invalid value '{value}' for enum {typeof(T).Name}");
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
to be used on the generated enum classes
using System.Text.Json.Serialization;
[JsonConverter(typeof(CaseInsensitiveEnumConverter<MessageDirectionEnum>))]
public enum MessageDirectionEnum
Looking through the codebase for the csharp generator, there is a lot of custom logic around the enums already with the zeroBasedEnums config option, so ideally we wouldn't want to break that
Describe alternatives you've considered
Clients can set an option to use caseInsensitive serialization - but it would be nice to have this built in
new JsonSerializerOptions
{
Converters = { new JsonStringEnumConverter() },
PropertyNameCaseInsensitive = true
});
With some guidance on how the config options dictate what is generated in the templates i could take a crack at implementing this - I have contributed to the templates previously - but not connected the build args to whats generated yet - so if there is any guidance or old PRs to look at, I'd be willing to take a crack at it
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the C# generator's enum templates and configuration handling, using the existing zeroBasedEnums option as the comparison point. Determine how configuration values reach generated enum classes and locate the relevant generator tests; done means the new setting works without breaking zeroBasedEnums behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, openapi
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100