RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.78k stars 1.29k forks source link

Nested arrays generating incorrect nested generics #3284

Open SartriX opened 3 years ago

SartriX commented 3 years ago

using Nswag.ApiDescriptionClient 13.10.1 on .Net Core 5.0.2 I'm having several issues generating a client from the public openApi: https://bag.basisregistraties.overheid.nl/api/v1 One issue is: Within it are several polygon objects which contain nested arrays, and these nested arrays are causing compile errors.

This is one of the schema objects defined in the yml spec:

    Polygon:
      description: "GeoJSON polygon geometry"
      type: "object"
      allOf:
      - $ref: "#/components/schemas/Geometry"
      - required:
        - "coordinates"
        type: "object"
        properties:
          coordinates:
            type: "array"
            items:
              type: "array"
              items:
                $ref: "#/components/schemas/Point2D"
      externalDocs:
        url: "https://tools.ietf.org/html/rfc7946#section-3.1.6"

resulting in:

        [Newtonsoft.Json.JsonProperty("coordinates", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public System.Collections.Generic.ICollection<System.Collections.Generic.ICollection<Point2D>> Coordinates { get; set; } = new System.Collections.ObjectModel.Collection<System.Collections.ObjectModel.Collection<Point2D>>();

Interface = Concrete does not compile. It would need to be Interface = Concrete

The correct generation would be:

public System.Collections.Generic.ICollection<System.Collections.Generic.ICollection<Point2D>> Coordinates { get; set; } = new System.Collections.ObjectModel.Collection<System.Collections.Generic.ICollection<Point2D>>();
RicoSuter commented 3 years ago

There are configs where you could set both array types to concrete ones

SartriX commented 3 years ago

I see something got dropped in the post: Interface<Interface> = Concrete<Concrete> does not compile. It would need to be Interface<Interface> = Concrete<Interface>

This should not be depending on any setting. I do like to keep the interfaces. Also: Which commandline setting would that be to get the full concrete behaviour? I'm using it from Visual Studio OpenApi integration.

miuliano commented 3 years ago

Ran into this issue, too. Nested types results in the following uncompilable code:

public System.Collections.Generic.IDictionary<string, System.Collections.Generic.ICollection<CustomItem>> CustomData { get; set; }
 = new System.Collections.Generic.Dictionary<string, System.Collections.ObjectModel.Collection<CustomItem>>();

For reference, the workaround mentioned above to replace the interfaces with concrete types can be done by adding the following in your csproj (if using OpenApiReference):

<Options>/ArrayType:System.Collections.ObjectModel.Collection</Options>