You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至.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'.
 ---&gt; 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配置时会触发序列化空引用错误。解决步骤如下:

  1. 升级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>
    
  2. 验证配置兼容性
    升级后无需修改现有的nswag.json和csproj配置,保持原结构即可。重新编译项目,NSwag将正常生成TypeScript模型。

若升级后仍有问题,可尝试删除项目的bin、obj目录及本地NuGet缓存,再重新构建。


内容的提问来源于stack exchange,提问作者Kvam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:05:55