RicoSuter / NSwag

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

JsonSerializationException after upgrading to NSwag.MSBuild 14 #4731

Open branko-d opened 5 months ago

branko-d commented 5 months ago

We have an ASP.NET Core project (.NET 7) which has controllers/actions exposing a Web API. We have been using NSwag.MSBuild to generate the corresponding TypeScript wrappers during build.

However, after upgrading NSwag.MSBuild package from 13.20.0 to 14.0.2, we started getting the following error every time we try to build:

------ Build started: Project: Epm.Web.Ui.Api, Configuration: Debug Any CPU ------
Epm.Web.Ui.Api -> C:\Users\brank\My\Repos\EProjects2-master\et\epm\Source\CS\Epm.Web.Ui.Api\bin\Debug\net7.0\Epm.Web.Ui.Api.dll
NSwag command line tool for .NET Core Net70, toolchain v14.0.2.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))
Visit http://NSwag.org for more information.
NSwag bin directory: C:\Users\brank\.nuget\packages\nswag.msbuild\14.0.2\tools\Net70

Executing file 'Properties\NSwag\api.nswag' with variables 'TargetFramework=net7.0,Configuration=Debug,Template=Types'...
Newtonsoft.Json.JsonSerializationException: Error setting value to 'SelectedSwaggerGeneratorRaw' on 'NSwag.Commands.NSwagDocument'.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at NSwag.Commands.NSwagDocumentBase.set_SelectedSwaggerGeneratorRaw(JObject value) in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 88
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.SetValue(Object target, Object value)
   --- End of inner exception stack trace ---
   at Newtonsoft.Json.Serialization.ExpressionValueProvider.SetValue(Object target, Object value)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at NSwag.Commands.NSwagDocumentBase.FromJson[TDocument](String filePath, String data) in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 222
   at NSwag.Commands.NSwagDocumentBase.LoadDocument[TDocument](String filePath, String data) in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 209
   at NSwag.Commands.NSwagDocumentBase.LoadAsync[TDocument](String filePath, String variables, Boolean applyTransformations) in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 203
   at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 64
   at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 33
   at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
   at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
   at NSwag.Commands.NSwagCommandProcessor.ProcessAsync(String[] args) in /_/src/NSwag.Commands/NSwagCommandProcessor.cs:line 62
C:\Users\brank\My\Repos\EProjects2-master\et\epm\Source\CS\Epm.Web.Ui.Api\Epm.Web.Ui.Api.csproj(37,9): error MSB3073: The command "dotnet "C:\Users\brank\.nuget\packages\nswag.msbuild\14.0.2\buildTransitive\../tools/Net70/dotnet-nswag.dll" run Properties\NSwag\api.nswag /variables:TargetFramework=net7.0,Configuration=Debug,Template=Types" exited with code -1.
Done building project "Epm.Web.Ui.Api.csproj" -- FAILED.

In case it's relevant, here is the NSwag-related portion of our .csproj file:

<Target Name="NSwagClients" AfterTargets="Build">
    <!-- Generate TypeScript type wrappers. -->
    <Exec Command="$(NSwagExe_Net70) run Properties\NSwag\api.nswag /variables:TargetFramework=$(TargetFramework),Configuration=$(Configuration),Template=Types" />
    <!-- Generate TypeScript method wrappers. -->
    <Exec Command="$(NSwagExe_Net70) run Properties\NSwag\api.nswag /variables:TargetFramework=$(TargetFramework),Configuration=$(Configuration),Template=Clients" />
</Target>

And here is our Properties/NSwag/api.nswag:

{
  "runtime": "Net70",
  "defaultVariables": null,
  "documentGenerator": {
    "webApiToOpenApi": {
      "controllerNames": [],
      "isAspNetCore": true,
      "resolveJsonOptions": false,
      "defaultUrlTemplate": "api/{controller}/{action}/{id?}",
      "addMissingPathParameters": false,
      "includedVersions": null,
      "defaultPropertyNameHandling": "CamelCase",
      "defaultReferenceTypeNullHandling": "NotNull",
      "defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
      "defaultResponseReferenceTypeNullHandling": "NotNull",
      "defaultEnumHandling": "Integer",
      "flattenInheritanceHierarchy": false,
      "generateKnownTypes": true,
      "generateEnumMappingDescription": false,
      "generateXmlObjects": false,
      "generateAbstractProperties": false,
      "generateAbstractSchemas": true,
      "ignoreObsoleteProperties": false,
      "allowReferencesWithProperties": false,
      "excludedTypeNames": [],
      "serviceHost": null,
      "serviceBasePath": null,
      "serviceSchemes": [],
      "infoTitle": "My Title",
      "infoDescription": null,
      "infoVersion": "1.0.0",
      "documentTemplate": null,
      "documentProcessorTypes": [],
      "operationProcessorTypes": [],
      "typeNameGeneratorType": null,
      "schemaNameGeneratorType": null,
      "contractResolverType": null,
      "serializerSettingsType": null,
      "useDocumentProvider": true,
      "documentName": "v1",
      "aspNetCoreEnvironment": null,
      "createWebHostBuilderMethod": null,
      "startupType": null,
      "allowNullableBodyParameters": false,
      "output": null,
      "outputType": "Swagger2",
      "assemblyPaths": [
        "../../bin/$(Configuration)/$(TargetFramework)/Epm.Web.Ui.Api.dll"
      ],
      "assemblyConfig": null,
      "referencePaths": [],
      "useNuGetCache": false
    }
  },
  "codeGenerators": {
    "openApiToTypeScriptClient": {
      "className": "{controller}",
      "moduleName": "",
      "namespace": "",
      "typeScriptVersion": 4.0,
      "template": "Fetch",
      "promiseType": "Promise",
      "httpClass": "Http",
      "withCredentials": false,
      "useSingletonProvider": false,
      "injectionTokenType": "OpaqueToken",
      "rxJsVersion": 6.0,
      "dateTimeType": "String",
      "nullValue": "Undefined",
      "generateClientClasses": true,
      "generateClientInterfaces": false,
      "generateOptionalParameters": true,
      "exportTypes": true,
      "wrapDtoExceptions": false,
      "exceptionClass": "SwaggerException",
      "clientBaseClass": null,
      "wrapResponses": false,
      "wrapResponseMethods": [],
      "generateResponseClasses": true,
      "responseClass": "SwaggerResponse",
      "protectedMethods": [],
      "configurationClass": null,
      "useTransformOptionsMethod": false,
      "useTransformResultMethod": false,
      "generateDtoTypes": true,
      "operationGenerationMode": "MultipleClientsFromOperationId",
      "markOptionalProperties": true,
      "generateCloneMethod": false,
      "typeStyle": "Interface",
      "classTypes": [],
      "extendedClasses": [],
      "extensionCode": null,
      "generateDefaultValues": true,
      "excludedTypeNames": [],
      "excludedParameterNames": [],
      "handleReferences": false,
      "generateConstructorInterface": true,
      "convertConstructorInterfaceData": false,
      "importRequiredTypes": false,
      "useGetBaseUrlMethod": false,
      "baseUrlTokenName": "API_BASE_URL",
      "queryNullValue": "",
      "inlineNamedDictionaries": false,
      "inlineNamedAny": false,
      "templateDirectory": "Templates/$(Template)",
      "typeNameGeneratorType": null,
      "propertyNameGeneratorType": null,
      "enumNameGeneratorType": null,
      "serviceHost": null,
      "serviceSchemes": null,
      "output": "../../../Epm.Web.Ui.Client/src/api/generated/$(Template).ts"
    }
  }
}
qFamouse commented 4 months ago

Did you manage to fix it?

chester23491 commented 4 months ago

The webApiToOpenApi was removed in version 14. You need to use the aspNetCoreToOpenApi command when you want to use it. I'm still struggling with the migration, since there is no migration guide. Good luck!

Valsy30 commented 1 month ago

The webApiToOpenApi was removed in version 14. You need to use the aspNetCoreToOpenApi command when you want to use it. I'm still struggling with the migration, since there is no migration guide. Good luck!

When I am using aspNetCoreToOpenApi to replace webApiToOpenApi, my PC will be hanging.