RicoSuter/NJsonSchema

Help with FromSampleJson

Open

#911 aperta il 27 feb 2019

Vedi su GitHub
 (3 commenti) (0 reazioni) (0 assegnatari)C# (550 fork)github user discovery
help wantedtype: enhancement

Metriche repository

Star
 (1578 star)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

Hello,

I'm currently seeing the following behavior when using JsonSchema4.FromSampleJson()

I have a JSON file consisting of a few properties with ids

{
  "version": "1.0",
  "components": {
    "comp1": {
      "id": "1"
    },
    "comp2": {
      "id": "2"
    },
    "comp3": {
      "id": "3",
      "resources": {
        "nestedcomp1": {
          "id": "4"
        },
        "nestedcomp2": {
          "id": "5"
        }
      }
    }
  }
}

And when I run the C# class generator, I get the following output:

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.12.7.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Components 
    {
        [Newtonsoft.Json.JsonProperty("comp1", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Comp1 Comp1 { get; set; } = new Comp1();
    
        [Newtonsoft.Json.JsonProperty("comp2", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Comp1 Comp2 { get; set; } = new Comp1();
    
        [Newtonsoft.Json.JsonProperty("comp3", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Comp3 Comp3 { get; set; } = new Comp3();
    
        public string ToJson() 
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }
        
        public static Components FromJson(string data)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<Components>(data);
        }
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.12.7.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Comp1 
    {
        [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Id { get; set; }
    
        public string ToJson() 
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }
        
        public static Comp1 FromJson(string data)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<Comp1>(data);
        }
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.12.7.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Comp3 
    {
        [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Id { get; set; }
    
        [Newtonsoft.Json.JsonProperty("resources", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Resources Resources { get; set; } = new Resources();
    
        public string ToJson() 
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }
        
        public static Comp3 FromJson(string data)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<Comp3>(data);
        }
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.12.7.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class Resources 
    {
        [Newtonsoft.Json.JsonProperty("nestedcomp1", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Comp1 Nestedcomp1 { get; set; } = new Comp1();
    
        [Newtonsoft.Json.JsonProperty("nestedcomp2", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Comp1 Nestedcomp2 { get; set; } = new Comp1();
    
        public string ToJson() 
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }
        
        public static Resources FromJson(string data)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<Resources>(data);
        }
    
    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.12.7.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class CoverageProfile 
    {
        [Newtonsoft.Json.JsonProperty("version", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Version { get; set; }
    
        [Newtonsoft.Json.JsonProperty("components", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public Components Components { get; set; } = new Components();
    
        public string ToJson() 
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }
        
        public static CoverageProfile FromJson(string data)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<CoverageProfile>(data);
        }
    
    }

Notice that most properties are now of the same type, Comp1. After some experimenting, I'm assuming that this is because when it parses comp1 attribute from JSON, it creates an appropriate C# class with an "id" property and every time it finds another JSON attribute that shares the same type, it reuses the one that it already made. While this seems like a smart optimization (which is why I'm thinking this is intended), it does get us into the scenario where if we were to add another property to the json before comp1, say comp0, all of our classes would need updating to comp0, since that is now the first property to have an {id: string} object type.

I tested changing the "id" property from comp2 to "id2" and it did create an entirely different class for comp2.

The question is, can I either

  1. Configure this so that a class is created for everything, even though the share the same property.
  2. Configure (the JSON, I assume) so that {id: string} is it's own type (let's say componentProperty) and reuse it everywhere, instead of it grabbing the first name that it sees? I'm trying to do this without a JSON schema.

Thank you

Guida contributor