christianhelle / refitter

A tool for generating Refit interfaces and contracts from OpenAPI specifications
https://refitter.github.io
MIT License
180 stars 39 forks source link

The using of StringEnumConverter end up generating unserializable data when different NamingPolicy is needed #178

Open attilah opened 11 months ago

attilah commented 11 months ago

Describe the bug This problem is with the same API as in #175, they use snake_lower_case for enum values and because JsonConverter will instantiate the JsonStringEnumConverter with default options the deserialization of any type with enum members will fail.

Registering a JsonStringEnumConverter in json serialization settings does not help, because as JsonConverter says: "When placed on a property or field, the specified converter will always be used.".

When JsonConverter is placed on the type, if you've a compatible serializer in settings that will be used.

I see multiple solutions here, but one of them is simple:

Now:

public enum Foo
{
    FooOne = 0,
    FooTwo = 1
}

public class FooClass
{
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public Foo enumValue { get; set; }
}

With fix:

[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Foo
{
    FooOne = 0,
    FooTwo = 1
}

public class FooClass
{
    public Foo enumValue { get; set; }
}

This way there is no requirement to have settings configured for enums, but gives the flexibility to have the behavior changed or register even typed enum converters there.

Support Key: [my-support-key] N/A

OpenAPI Specifications Same as in #175

Additional context [EnumMember] is not used with System.Text.Json so their declaration can be omitted.

christianhelle commented 11 months ago

@attilah thanks for taking the time to report this

I looked a bit into this and there is very little I can do regarding changing how the contracts/dto types are generated. I piggy back entirely on a tool called NSwag for parsing the OpenAPI spec and for generating contracts.

Implementing customizations to the generated contracts/dto types would require building them by hand, and that's a bit of a big task, which I'm not ready to start on yet. I've done it previously in another project I'm involved in called the ATC REST Generator and it was rather hard to do and we kept seeing bugs.

NSwag seems to have nailed the contract/dto type generation to the point where everyone can almost be happy, but the feature set for generating contract/dto types hasn't really changed much over the years

I'll park this for now and revisit it in the future if I decide that Refitter should also handle contract/dto type generation.

May I suggest that you try other code generators and see if any of the others (e.g. OpenAPI Generator, NSwag, Kiota) can solve your problem? I have a Visual Studio extension that can help with trying out different code generators