RicoSuter / NJsonSchema

JSON Schema reader, generator and validator for .NET
http://NJsonSchema.org
MIT License
1.37k stars 529 forks source link

Generation of C# Code OneOf not working #673

Open screig opened 6 years ago

screig commented 6 years ago

First off this is a great library! Well done.

I am seeing an issue with the generation of OneOf code. The generated C# only shows the first choice.

        WebClient client = new WebClient();
        Stream stream = client.OpenRead("https://raw.githubusercontent.com/ANNA-DSB/Product-Definitions/master/PROD/JSON/Credit/Credit.Swap.ABS.InstRefDataReporting.V1.json");
        StreamReader reader = new StreamReader(stream);
        string jsonString = reader.ReadToEnd();

        //string jsonString = File.ReadAllText("Credit.Swap.ABS.InstRefDataReporting.V1.json");

        var myschema = await JsonSchema4.FromJsonAsync(jsonString);
        var generator = new CSharpGenerator(myschema);
        var createdCode = generator.GenerateFile();
        File.WriteAllText("out.cs", createdCode);

The relevant part of the JSON is this part, where a one of two types is specified:

    "Underlying": {
      "title": "Underlying",
      "type": "object",
      "oneOf": [
        {
          "type": "object",
          "title": "InstrumentISIN",
          "properties": {
            "InstrumentISIN": {
              "title": "Instrument ISIN",
              "description": "ISIN code of the underlying instrument",
              "type": "string",
              "pattern": "^[A-Z]{2}[A-Z0-9]{9}[0-9]$"
            }
          },
          "required": [
            "InstrumentISIN"
          ],
          "additionalProperties": false
        },
        {
          "type": "object",
          "title": "**InstrumentLEI**",
          "properties": {
            "InstrumentLEI": {
              "title": "Instrument LEI",
              "description": "In case the instrument is referring to an issuer, rather than to one single instrument, the LEI code of the Issuer",
              "type": "string",
              "pattern": "^[A-Z0-9]{18}[0-9]{2}$"
            }
          },
          "required": [
            "InstrumentLEI"
          ],
          "additionalProperties": false
        }
      ]
    },

The generated C# code looks like this, namely the second choice has disappeared.

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.10.42.0 (Newtonsoft.Json v9.0.0.0)")]
public partial class Underlying : System.ComponentModel.INotifyPropertyChanged
{
    private string _instrumentISIN;

    /// <summary>ISIN code of the underlying instrument</summary>
    [Newtonsoft.Json.JsonProperty("InstrumentISIN", Required = Newtonsoft.Json.Required.Always)]
    [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
    [System.ComponentModel.DataAnnotations.RegularExpression(@"^[A-Z]{2}[A-Z0-9]{9}[0-9]$")]
    public string InstrumentISIN
    {
        get { return _instrumentISIN; }
        set 
        {
            if (_instrumentISIN != value)
            {
                _instrumentISIN = value; 
                RaisePropertyChanged();
            }
        }
    }

    public string ToJson() 
    {
        return Newtonsoft.Json.JsonConvert.SerializeObject(this);
    }

    public static Underlying FromJson(string data)
    {
        return Newtonsoft.Json.JsonConvert.DeserializeObject<Underlying>(data);
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) 
            handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

}

Am I doing something incorrectly? Thanks Sean

RicoSuter commented 6 years ago

oneOf inheritance is currently not supported in the code generators. It's an outstanding issue and not so simple to implement:

https://github.com/RSuter/NSwag/issues/1136

screig commented 6 years ago

thanks for the quick feedback.

RicoSuter commented 5 years ago

oneOf inheritance is now implemented and handled by default, please retest with latest version.

MatSFT commented 5 years ago

This still doesn't seem to work for one of. The first schema from the one of list is the one that is chosen.

RicoSuter commented 5 years ago

I think my previous statement was wrong - just allOf inheritance has been improved. OneOf inheritance is another story, see PR https://github.com/RSuter/NJsonSchema/pull/839 and associated issues

MatSFT commented 5 years ago

bummer. For the code gen piece of one of would it be sufficient to just squash all the one of schemas into one object? I can't even think of how else to do it.