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

oneOf support in NSwag.CodeGeneration.CSharp.SwaggerToCSharpClientGenerator #1721

Open
cpjolly opened this issue Nov 7, 2018 · 10 comments
Open

Comments

@cpjolly
Copy link

cpjolly commented Nov 7, 2018

Hello @RSuter,

does NSwag.CodeGeneration.CSharp.SwaggerToCSharpClientGenerator currently support oneOf ? It seems to only convert the first item but ignores the second and following items.

Here is the part of the schema in question:

"framework-attribute-interface": {
            "type": "object",
            "description": "Interface for custom attribute value.",
            "properties": {
                "attribute_code": {
                    "type": "string",
                    "description": "Attribute code"
                },
                "value": {
                    oneOf: [
                        {
                            "type": "string",
                            "description": "Attribute value"
                        },
                        {
                            "type": "array",
                            "description": "Attribute values",
                            "items": {
                                "type": "string",
                                "description": "Attribute value"
                            }
                        }
                    ]
                }
            },
            "required": ["attribute_code", "value"]
        }

And here is the generated code:

    /// <summary>Interface for custom attribute value.</summary>
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "9.11.0.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class FrameworkAttributeInterface : System.ComponentModel.INotifyPropertyChanged
    {
        private string _attribute_code;
        private string _value;
    
        /// <summary>Attribute code</summary>
        [Newtonsoft.Json.JsonProperty("attribute_code", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
        public string Attribute_code
        {
            get { return _attribute_code; }
            set 
            {
                if (_attribute_code != value)
                {
                    _attribute_code = value; 
                    RaisePropertyChanged();
                }
            }
        }
    
        [Newtonsoft.Json.JsonProperty("value", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
        public string Value
        {
            get { return _value; }
            set 
            {
                if (_value != value)
                {
                    _value = value; 
                    RaisePropertyChanged();
                }
            }
        }
    
        public string ToJson() 
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }
        
        public static FrameworkAttributeInterface FromJson(string data)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<FrameworkAttributeInterface>(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));
        }
    
    }
@RicoSuter
Copy link
Owner

No this is not supported. What would you expect as c# output for the property?

@RicoSuter
Copy link
Owner

Related: RicoSuter/NJsonSchema#13

@cpjolly
Copy link
Author

cpjolly commented Nov 8, 2018

Hi @RSuter,

There are two possible approaches I can think of to support oneOf, anyOf & allOf in the generated c#.

  1. A separate field for each of the oneOf options, plus an enum flag field to indicate which is the active field or fields.
  2. A separate entity with the same option & enum fields, that is referenced from the parent entity.

In the mean time, the work-around I thought of is something like overriding the calling method in the generated code, pass a custom JsonConverter method to SerializeObject(), where the custom JsonConvertor converts the oneOf part of the json stream ?

Please let me know if I can help further.

Many thanks

Chris Jolly

@RicoSuter
Copy link
Owner

Yes, and also there is different output when oneOf is used for inheritance vs. your scenario here..

@RicoSuter
Copy link
Owner

Maybe the simplest solution in this case would be to just generate an object/JToken property...

@cpjolly
Copy link
Author

cpjolly commented Nov 8, 2018

Hi @RSuter,

Perhaps JToken is the right answer. Sorry, I don't know enough about the inner workings of your code or Newtonsoft to know if that's the right approach... I'd also be interested to know how easy it was to work with the resulting entities after deserialization.

@RicoSuter
Copy link
Owner

Hmm, I dont like exposing JToken or Newtonsoft.Json specific stuff (leaky abstraction) so maybe it's better to just expose object, but then the property is completely untyped - i.e. in your case not only string and string[] is allowed but everything...

Can you create a new issue in NJsonSchema for this? Because it has to be implemented there (DTO handling is in this library)

@cpjolly
Copy link
Author

cpjolly commented Nov 8, 2018

OK - I've created a new issue in NJsonSchema. Please let me know if you want me to copy over the example code from the above description

@WarrenFerrell
Copy link

WarrenFerrell commented Feb 6, 2020

@RicoSuter I believe this should be closed as a duplicate of #2313 ?

@jeremyVignelles
Copy link
Collaborator

I didn't read it through, but could it be merged with #2991 ?

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

4 participants