升级至.NET 8后Mac上NSwag TypeScript模型生成失败
问题
将项目从.NET 7升级至.NET 8后,Mac环境下使用NSwag生成TypeScript模型失败,除.NET版本外未修改任何配置文件。
已安装NuGet包
<PackageReference Include="NSwag.AspNetCore" Version="14.0.1" /> <PackageReference Include="NSwag.MSBuild" Version="14.0.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference>
nswag.json配置
{ "runtime": "Net80", "documentGenerator": { "webApiToOpenApi": { "isAspNetCore": true, "defaultPropertyNameHandling": "CamelCase", "defaultReferenceTypeNullHandling": "NotNull", "defaultEnumHandling": "String", "assemblyPaths": [ "bin/$(Configuration)/net8.0/MyProject.Web.Api.dll" ] } }, "codeGenerators": { "openApiToTypeScriptClient": { "typeScriptVersion": 4.8, "dateTimeType": "Date", "nullValue": "Undefined", "generateClientClasses": false, "exceptionClass": "SwaggerException", "typeStyle": "Interface", "output": "../../../frontend/src/types/contracts/nswag-contracts.d.ts" } } }
csproj配置
<Target Name="NSwag" AfterTargets="Build"> <Exec Command="$(NSwagExe_Net80) run nswag.json /variables:Configuration=$(Configuration)" /> </Target>
编译错误日志
Executing file 'nswag.json' with variables 'Configuration=Debug'... 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 1>MyProject.Web.Api.csproj(37,9): Error MSB3073 : The command "dotnet "/Users/frank/.nuget/packages/nswag.msbuild/14.0.1/buildTransitive/../tools/Net80/dotnet-nswag.dll" run nswag.json /variables:Configuration=Debug" exited with code 255. 1>------- Finished building project: MyProject.Web.Api. Succeeded: False. Errors: 1. Warnings: 0
解决方案
这个问题是NSwag 14.0.1版本对.NET 8的兼容性缺陷导致的,该版本在解析nswag.json配置时会触发序列化空引用错误。解决步骤如下:
升级NSwag包版本
将NSwag.AspNetCore和NSwag.MSBuild的版本升级到14.1.1及以上(或最新稳定版),该版本修复了.NET 8适配的相关问题。修改后的NuGet配置示例:<PackageReference Include="NSwag.AspNetCore" Version="14.1.1" /> <PackageReference Include="NSwag.MSBuild" Version="14.1.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference>验证配置兼容性
升级后无需修改现有的nswag.json和csproj配置,保持原结构即可。重新编译项目,NSwag将正常生成TypeScript模型。
若升级后仍有问题,可尝试删除项目的bin、obj目录及本地NuGet缓存,再重新构建。
内容的提问来源于stack exchange,提问作者Kvam
相关产品推荐
相关产品推荐

