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

Cannot cast Collection to ICollection #3189

Closed
btrepp opened this issue Nov 24, 2020 · 4 comments · Fixed by RicoSuter/NJsonSchema#1511
Closed

Cannot cast Collection to ICollection #3189

btrepp opened this issue Nov 24, 2020 · 4 comments · Fixed by RicoSuter/NJsonSchema#1511

Comments

@btrepp
Copy link

btrepp commented Nov 24, 2020

Added the openapi tools from https://docs.microsoft.com/en-us/aspnet/core/web-api/microsoft.dotnet-openapi?view=aspnetcore-5.0

Which seem to use Nswag tor client generation. Unsure if the issue is here or perhaps with the tool.
Ultimately it generates code

/// <summary>The list of data rows, each row being a list of cell contents.</summary>
        [Newtonsoft.Json.JsonProperty("data", Required = Newtonsoft.Json.Required.Always)]
        [System.ComponentModel.DataAnnotations.Required]
        public System.Collections.Generic.ICollection<System.Collections.Generic.ICollection<object>> Data { get; set; } = new System.Collections.ObjectModel.Collection<System.Collections.ObjectModel.Collection<object>>();

which is uncompilable with

'System.Collections.ObjectModel.Collection<System.Collections.ObjectModel.Collection<object>>' to 'System.Collections.Generic.ICollection<System.Collections.Generic.ICollection<object>>'. An explicit conversion exists (are you missing a cast?)

Which looks like it comes from

"GenericTableOutputV1": {
      "type": "object",
      "properties": {
        "headers": {
          "description": "The list of headers.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/TableColumnOutputV1"
          }
        },
        "data": {
          "description": "The list of data rows, each row being a list of cell contents.",
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "required": [
        "data",
        "headers"
      ]

I can manually tweak the outputted file and then it compiles, but that may be tricky on a build server.

@CNBoland
Copy link

I'm experiencing this, too. To work around the build error, I add this parameter to the generator:

/ArrayType:System.Collections.Generic.IEnumerable

@RicoSuter
Copy link
Owner

RicoSuter commented Jan 28, 2021

So collection is not assignable to icollection?

Ah no its an array of arrays and required.

@thomasjoscht
Copy link

Same problem here. Solved by changing ArrayType from ICollection to IEnumerable.

openapi.json

Here are the parts which has lead to my problem (Property Tubles).

"ms-PredicateJointElementList" : {
        "title" : "Joint Element List Predicate",
        "description" : "Specialized expression node that contains a joint element list predicate.\n\nThis qualification represents a filter at the level of two or more attributes.\nThe filter is defined by simply listing the tuples of elements that satisfy\nthe filter.\n",
        "allOf" : [ {
          "$ref" : "#/components/schemas/ms-PredicateBase"
        }, {
          "type" : "object",
          "properties" : {
            "predicateTree" : {
              "required" : [ "level", "tuples" ],
              "type" : "object",
              "properties" : {
                "level" : {
                  "type" : "array",
                  "description" : "The level of this filter represented as an array of attributes. The attributes must be different from each other, and their order is significant.",
                  "items" : {
                    "$ref" : "#/components/schemas/ms-ObjectInfoReference"
                  }
                },
                "tuples" : {
                  "type" : "array",
                  "description" : "An array of tuples of elements.\n\nEach element of this array is a _joint element_.\nThat is the members of this array are themselves arrays of elements.\nThe elements in the tuples *must* be listed in the same order as the attributes were\nlisted in the `level` array.  There is no need to list the attribute on each element.\n",
                  "items" : {
                    "type" : "array",
                    "description" : "A tuple of elements, with one element for each attribute in the `level`",
                    "items" : {
                      "$ref" : "#/components/schemas/ms-ElementConcrete"
                    }
                  }
                }
              }
            }
          }
        } ]
      }

C# Code

The generated C# code before and after my change.

// before error because of invalid cast => BUILD FAILED
ICollection<ICollection<object>> tubles = new Collection<Collection<object>>();

// ....

// after changing to IEnumerable => OK
IEnumerable<IEnumerable<object>> tubles = new Collection<Collection<object>>();

C# Code suggestion

Alternative the code generation must be enhanced to use Collection of ICollection.

// alternative array in array must be defined as following
ICollection<ICollection<object>> tubles = new Collection<ICollection<object>>();

Regards
Thomas

@swurzinger
Copy link

similar issue for Dictionaries.

original definition: IDictionary<string, string[]> Errors

swagger json:

"errors": {
	"type": "object",
	"additionalProperties": {
		"type": "array",
		"items": {
			"type": "string"
		}
	}
}

generated C# code:

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

Note the ICollection vs. Collection type differences in the generic type arguments. NSwag seems to use the "Generic Array Instance Type" for the type argument, while the "Generic Array Type" should be used.

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

Successfully merging a pull request may close this issue.

5 participants