Dictionary type mapping issue in .net 8
Closed this issue · 1 comments
First time reporting an issue, if I step wrong, please let me know.
I am upgrading projects to .net 8 from .net 7. Using NSwag 14.1.0
In my service layer I have a model being returned with the following definition:
public Dictionary<PageSize, WidgetLocation> Location { get; set; }
PageSize is an enum
WidgetLocation is a class
OpenAPI Reference:
<OpenApiReference Include="OpenAPIs\Query.UI.json" CodeGenerator="NSwagCSharp" Namespace="IML.Core.ServiceClients.Query.UI" Options="/OperationGenerationMode:MultipleClientsFromOperationId /GenerateClientInterfaces:true /AdditionalNamespaceUsages:IML.Core.ServiceClients.Query,System /GenerateUpdateJsonSerializerSettingsMethod:false /ClientBaseClass:NSwagBase /DateTimeType:DateTime" ClassName="UIClient">
<SourceUri>http://localhost:8085/swagger/v1/swagger.json</SourceUri>
</OpenApiReference>
Here is what the generated stuff looks like:
/// <summary>
/// Gets or sets the dictionary of widget locations for different page sizes.
/// </summary>
[Newtonsoft.Json.JsonProperty("location", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Location Location { get; set; }
/// <summary>
/// Gets or sets the dictionary of selected options for the widget.
/// </summary>
[Newtonsoft.Json.JsonProperty("selectedOptions", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public System.Collections.Generic.IDictionary<string, string> SelectedOptions { get; set; }
You can see a dictionary value named SelectedOptions that works fine of type Dictionary<string, string>
I've attempted a number of fixes. However, anything I do seems to fail in one way or another.
Based on chat gpt's recommendation I attempted to add a type mapping to resolve it like so:
{
"runtime": "Net80",
"documentGenerator": {
"fromDocument": {
"url": "http://localhost:8085/swagger/v1/swagger.json"
}
},
"codeGenerators": {
"openApiToCSharpClient": {
"className": "UIClient",
"namespace": "IML.Core.ServiceClients.Query.UI",
"clientBaseClass": "NSwagBase",
"generateClientInterfaces": true,
"operationGenerationMode": "MultipleClientsFromOperationId",
"additionalNamespaceUsages": [
"IML.Core.ServiceClients.Query",
"System"
],
"generateUpdateJsonSerializerSettingsMethod": false,
"dateTimeType": "DateTime",
"typeMappings": {
"Location": "System.Collections.Generic.Dictionary<PageSize, WidgetLocation>"
}
}
}
}
Doing so outputs this error immediately:
MSB3073 The command "dotnet --roll-forward-on-no-candidate-fx 2 "C:\Users\cjchambers\.nuget\packages\nswag.msbuild\14.1.0\buildTransitive\../tools/Net80//dotnet-nswag.dll" openapi2csclient /className:UIClient /namespace:IML.Core.ServiceClients.Query.UI /generateExceptionClasses:false /input:"D:\GITWorkspace\Libraries\IML.Core\IML.Core.ServiceClients.Query\OpenAPIs\Query.UI.json" /output:"D:\GITWorkspace\Libraries\IML.Core\IML.Core.ServiceClients.Query\obj\Query.UIClient.cs" D:\GITWorkspace\Libraries\IML.Core\IML.Core.ServiceClients.Query\UI.json /generateResponseClasses:false" exited with code -1. IML.Core.ServiceClients.Query C:\Users\cjchambers\.nuget\packages\nswag.apidescription.client\14.1.0\build\NSwag.ApiDescription.Client.targets 285
Which is interesting because when I started this, the first problem I had to resolve was that "/generateExceptionClasses:false" was throwing an error. Including it results in failure.
So based on AI advice I attempted to customize the generation with this:
<Target Name="CustomNSwagGeneration" BeforeTargets="Build">
<!-- Custom NSwag command -->
<Exec Command='dotnet --roll-forward-on-no-candidate-fx 2 "$(MSBuildThisFileDirectory)nswag.json" openapi2csclient /input:"$(MSBuildThisFileDirectory)OpenAPIs\Query.UI.json" /output:"$(MSBuildThisFileDirectory)obj\Query.UIClient.cs"' />
</Target>
But this gave me the same error.
FYI.
I managed to resolve this. It was due to the API having a reference to Swashbuckle.AspNetCore 6.7.0 (recently upgraded as part of .net 8 upgrade) - setting up a new project revealed this worked just fine with the version that comes standard (6.4.0)
So for anyone else experiencing issues, that was my resolution.