CoreWCF icon indicating copy to clipboard operation
CoreWCF copied to clipboard

WebHttp OpenAPI is generating excessive types

Open samsp-msft opened this issue 2 years ago • 2 comments

I have been working on cleaning up the samples and creating clients to go with the server examples. In the case of the webhttp binding, the client uses the Nswag msbuild task to generate a client wrapper based on the swagger document generated.

The problem that I am finding is how its handling inner types.

The server contract includes:

    [DataContract(Name = "ExampleContract", Namespace = "http://example.com")]
    internal class ExampleContract
    {
        [DataMember(Name = "SimpleProperty", Order = 1)]
        [OpenApiProperty(Description = "SimpleProperty description.")]
        public string SimpleProperty { get; set; }

        [DataMember(Name = "ComplexProperty", Order = 2)]
        [OpenApiProperty(Description = "ComplexProperty description.")]
        public InnerContract ComplexProperty { get; set; }

        [DataMember(Name = "SimpleCollection", Order = 3)]
        [OpenApiProperty(Description = "SimpleCollection description.")]
        public List<string> SimpleCollection { get; set; }


        [DataMember(Name = "ComplexCollection", Order = 4)]
        [OpenApiProperty(Description = "ComplexCollection description.")]
        public List<InnerContract> ComplexCollection { get; set; }
    }

    [DataContract(Name = "InnerContract", Namespace = "http://example.com")]
    internal class InnerContract
    {
        [DataMember(Name = "Name", Order = 1)]
        [OpenApiProperty(Description = "Name description.")]
        public string Name { get; set; }
    }
}

I get a generated client (yay). but when I then look at the code generated it has:

 public partial class ExampleContract
{ 
        [Newtonsoft.Json.JsonProperty("ComplexProperty", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public ExampleContractInnerContract ComplexProperty { get; set; }
...    
        /// <summary>ComplexCollection description.</summary>
        [Newtonsoft.Json.JsonProperty("ComplexCollection", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Collections.Generic.ICollection<ExampleContractArrayInnerContract> ComplexCollection { get; set; }
}

In the original contract, there is one type InnerContract, but here its deciding to create multiple types ExampleContractInnerContract and ExampleContractArrayInnerContract, which should be the same. This bloats the type table, and means that they can't be used across methods. Is there something going wrong in the swagger generation that is causing this?

@JonathanHopeDMRC - can you help?

samsp-msft avatar May 06 '22 21:05 samsp-msft

I agree it definitely looks weird, and the initial version of this didn't have the duplicated types. Unfortunately while the initial version worked wonderfully for JSON it didn't really work at all for XML. It mostly came down to how strict XML is, and how poorly suited OpenAPI is at representing it.

It's possible that we've struck the wrong balance here in pursuit of the XML support. I'll reach out to @mconnew about this,

JonathanHopeDMRC avatar May 06 '22 22:05 JonathanHopeDMRC

I tried to get the client generation working for XML for .NET. There are multiple generators which exist across multiple projects and the XML client generation ranges from doesn't support at all to there's beginnings of some support and even that is majorly buggy. But for .NET at least, there is no viable option for generating an XML based client from OpenAPI. I haven't surveyed the options for other languages though. If other language generators have as poor XML based client generation, we should probably drop the OpenAPI XML support in 2.0. If there are generators for other languages which are functional, then we need to decide how important it is. I think WebHttpBinding supports WSDL in WCF. If so, once we have WebHttpBinding client support, I should enable WSDL support for WebHttpBinding and then that would be the recommended solution for XML with .NET.

mconnew avatar May 07 '22 00:05 mconnew