Skip to content

TypeSpec: .NET JSON serialization/deserialization for enums -- add generation of a custom converter? #3353

@trrwilson

Description

@trrwilson

When defining an enum type in TypeSpec, e.g.

enum Foo {
  first,
  second
}

The C# emitter generates a nice "enum-like class" that looks something like (partial):

public partial readonly struct Foo : IEquatable<Foo>
{
    private readonly string _value;

    public Foo(string value)
    {
        _value = value ?? throw new ArgumentNullException(nameof(value));
    }
    ...
    public static Foo First { get; } = new Foo(...);
    public static Foo Second { get; } = new Foo(...);
    ...
    public override string ToString() => _value;
}

Older versions of .NET don't automatically support System.Json.Text.Serialization capabilities for non-property / private fields, so calling System.Json.Text.Serialization.JsonSerializer.Serialize(new Foo("hello")) will not serialize the value string as intended. And subsequent deserialization will of course not be able to reflect the original object.

I think it's fairly easy to address this, fortunately. If the emitter can first create a customer converter (FooConverter.cs):

internal class FooConverter : JsonConverter<Foo>
{
    public override Foo Read(ref Utf8JsonReader reader, Type _, JsonSerializerOptions __) => new Foo(reader.GetString());
    public override void Write(Utf8JsonWriter writer, Foo value, JsonSerializerOptions _) => writer.WriteStringValue(value.ToString());
}

...and then the generated enum-like struct/class is attributed:

[JsonConverter(typeof(FooConverter))]
public partial readonly struct Foo: IEquatable<Foo>
{
...

...then I think everything ends up happy. This is possible now for emitter consumers via doing the above in custom code, but it'd be nice if were auto-generated.

Metadata

Metadata

Assignees

Labels

DPGinfrastructureRequired infrastructure work that is not a feature persay but required to keep things runningv3Version 3 of AutoRest C# generator.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions