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

Code produced by CSharpGenerator for enums does not work with System.Text.Json #1375

Open
virovets64 opened this issue Jun 9, 2021 · 2 comments

Comments

@virovets64
Copy link

Hello!
I'm trying to use CSharpGenerator to generate C# code from JSON schema. The schema contains enums with camelStyle members. But when I serialize the generated classes with System.Text.Json, the resulting JSON contains PascalStyle enums, which violates the schema.

To reproduce

Schema example:

{
  "$schema": "http://json-schema.org/schema#",
  "type": "object",
  "properties": {
    "starType": {
      "type": "string",
      "enum": [ "redGiant", "whiteDwarf" ]
    }
  }
}

I run the generator in the following way:

string code = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
  JsonLibrary = CSharpJsonLibrary.SystemTextJson,
  Namespace = "Example"
}).GenerateFile("Star");

Here is the code generated:

//----------------------
// <auto-generated>
//     Generated using the NJsonSchema v10.4.4.0 (Newtonsoft.Json v9.0.0.0) (http://NJsonSchema.org)
// </auto-generated>
//----------------------

namespace Example
{
    #pragma warning disable // Disable all warnings

    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.4.4.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Star 
    {
        [System.Text.Json.Serialization.JsonPropertyName("starType")]
        [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
        public StarType StarType { get; set; }
    
        private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
    
        [System.Text.Json.Serialization.JsonExtensionData]
        public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
        {
            get { return _additionalProperties; }
            set { _additionalProperties = value; }
        }
    
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.4.4.0 (Newtonsoft.Json v9.0.0.0)")]
    public enum StarType
    {
        [System.Runtime.Serialization.EnumMember(Value = @"redGiant")]
        RedGiant = 0,
    
        [System.Runtime.Serialization.EnumMember(Value = @"whiteDwarf")]
        WhiteDwarf = 1,
    
    }
}

Then I serialize the generated class:

static void Main(string[] args)
{
  var star = new Example.Star()
  {
    StarType = Example.StarType.RedGiant
  };
  string serialized = JsonSerializer.Serialize(star);
  Console.WriteLine(serialized);
}

The resulting JSON is

{
  "starType": "RedGiant"
}

Adding JsonStringEnumConverter has no effect:

string serialized = JsonSerializer.Serialize(star, new JsonSerializerOptions
{
  Converters =
  {
    new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
  }
});

Suggestions

  1. System.Runtime.Serialization.EnumMember attribute is ignored by System.Text.Json, see Support for EnumMemberAttribute in JsonConverterEnum dotnet/runtime#31081
  2. System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter)) attribute generated for StarType property overloads my JsonStringEnumConverter specified in JsonSerializerOptions.

I tried to find a workaround but failed.

Best regards,
Mikhail Virovets

@eholman
Copy link

eholman commented Sep 22, 2021

I'm having the exact issue where the EnumMemberAttribute value is not read. I also have a custom converter available, added to the JsonSerializerOptions of the generated client.

Currently I'm digging through the code of NJsonSchema. At this moment I think it should become optional to get the converter attribues generated in C#, regardless jsonLibrary setting - at this moment the option is not there.

{%   if property.IsStringEnum -%}
{%     if UseSystemTextJson -%}
    [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
{%     else -%}
    [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
{%     endif -%}
{%   endif -%}

@jochenjonc
Copy link
Contributor

jochenjonc commented Nov 26, 2021

I agree with @eholman, it should be optional to have the JsonConverter attribute added or not.
And if possible to use the JsonStringEnumMemberConvertor from the Macross.Json.Extensions or other custom one.

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

3 participants