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

Wrong initializer generated #1116

Closed
EricSch opened this issue Jan 14, 2020 · 11 comments · Fixed by #1511
Closed

Wrong initializer generated #1116

EricSch opened this issue Jan 14, 2020 · 11 comments · Fixed by #1511

Comments

@EricSch
Copy link

EricSch commented Jan 14, 2020

The generated code by NSwag.CodeGeneration.CSharp (Version="13.2.1") generates this code:
public System.Collections.Generic.IDictionary<string, System.Collections.Generic.ICollection<string>> AssetDerivations { get; set; } = new System.Collections.Generic.Dictionary<string, System.Collections.ObjectModel.Collection<string>>();
But this code can't be compiled:
Error CS0266 Cannot implicitly convert type 'System.Collections.Generic.Dictionary<string, System.Collections.ObjectModel.Collection<string>>' to 'System.Collections.Generic.IDictionary<string, System.Collections.Generic.ICollection<string>>'. An explicit conversion exists (are you missing a cast?)

The problem is between ObjectModel.Collection and Generic.ICollection. I know, I could change the configuration, but then I get similar problems in other places.

See also RicoSuter/NSwag#2496, seems to be a similar issue. Danke!

@RicoSuter
Copy link
Owner

Moved to NJS.

@quotschmacher
Copy link

Same here
[Required(AllowEmptyStrings = false)] [JsonProperty(Required = Required.DisallowNull, PropertyName = "DatabaseInsertRows")] public List<SyncColumn[]> DatabaseInsertRows { get; set; }

(SyncColumn is a simple object with two members)

generates
"databaseInsertRows": { "type": "array", "items": { "type": "array", "items": { "$ref": "#/components/schemas/SyncColumn" } } }

in the swagger JSON

what leads to
public System.Collections.Generic.ICollection<System.Collections.Generic.ICollection<SyncColumn>> DatabaseInsertRows { get; set; } = new System.Collections.ObjectModel.Collection<System.Collections.ObjectModel.Collection<SyncColumn>>();

and that cannot be compiled.

@RicoSuter
Copy link
Owner

Ok so the bug here is that the inner collection must be the original interface type and not the instance type.

@RicoSuter
Copy link
Owner

We'd need to fix this here somehow (it's a bit hacky right now - we need to refactor this quite a bit probably):
https://github.com/RicoSuter/NJsonSchema/blob/master/src/NJsonSchema.CodeGeneration.CSharp/CSharpValueGenerator.cs#L60

@aboryczko
Copy link
Contributor

Hi @RicoSuter, I would gladly work on this, as my team has issues migrating to .NET 6 because of this. I did a quick fix that just substituted the first part of the target type, but maybe you have something more sophisticated in mind. Could you provide some context on how this should be refactored?

@tanner-lewis
Copy link

@RicoSuter My team is also very interested in the proposed fix. It looks promising after a quick glance through the PR.

@vindberg
Copy link

vindberg commented May 4, 2022

@aboryczko Arthur would it also be possible to default to "List" instead of ICollection (when the DTO is a List). I am in Blazor and my current solution is to cast those icollections to lists which is a bit cumbersome. Thanks for any insight, love this free product :)

@aboryczko
Copy link
Contributor

@vindberg I think you could just use System.Collections.Generic.List for both ArrayType and ArrayInstanceType

@vindberg
Copy link

@aboryczko Thanks for getting back to me. I see all the options here: https://github.com/RicoSuter/NJsonSchema/wiki/CSharpGeneratorSettings Do you know how to define it in a Visual Studio project that uses OpenAPI in the Solution Project .csproj file:
<ItemGroup> <OpenApiReference Include="OpenAPIs\Collective.json" Options="/UseBaseUrl:false /exposeJsonSerializerSettings:true" Namespace="Website.HttpClients" ClassName="CollectiveClient"> <CodeGenerator>NSwagCSharp</CodeGenerator> </OpenApiReference> </ItemGroup>

Is it possible to define the settings in Startup or do I create a new class that inherits from NSwagCSharp and ref it in the .csproj file?

Thanks for any insight in this. I can't find documentation on this part.

@aboryczko
Copy link
Contributor

@vindberg you already have Options="...." just add two more i.e. /ArrayType:System.Collections.Generic.List /ArrayInstanceType:System.Collections.Generic.List

@vindberg
Copy link

Thank you so much - I had to edit the .json file to trigger a new automated class but it worked!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants