我正在探索基于 ASP.NET 服务器的 OpenAPI 规范自动生成客户端 TypeScript 代码的可能性。为了实现这一目标,我从 NuGet 安装了 NSwag.AspNetCore 包,并通过添加以下行更新了 Program.cs 文件:
builder.Services.AddOpenApiDocument();
app.UseOpenApi();
app.UseSwaggerUI();
使用Swagger UI成功获取OpenAPI链接后,我在NSwag Studio程序中使用它来生成可以在客户端使用的TypeScript代码。
现在,我想自动化这个过程。首先,我一直在尝试了解如何在每次使用 MSBuild 构建后设置自动代码生成,遵循其 GitHub 存储库上的 NSwag 文档中的指南 (https://github.com/RicoSuter/NSwag/wiki/NSwag .MSBuild).
我的ASP.NET项目分为几个类库:
Bets.WebUI:带有控制器和其他组件的 ASP.NET 项目 合约:带有 DTO 的类库 应用程序:包含处理用户请求(业务逻辑)等的类 首先,我安装了 NSwag.MSBuild 包并使用 NSwag Studio 生成了 nswag.json 文件。该文件包含以下设置:
{
"runtime": "Net70",
"defaultVariables": null,
"documentGenerator": {
"aspNetCoreToOpenApi": {
"project": "Bets.WebUI.csproj",
"documentName": "v1",
"msBuildProjectExtensionsPath": null,
"configuration": null,
"runtime": null,
"targetFramework": null,
"noBuild": false,
"msBuildOutputPath": null,
"verbose": true,
"workingDirectory": null,
"aspNetCoreEnvironment": null,
"output": null,
"newLineBehavior": "Auto"
}
},
"codeGenerators": {
"openApiToTypeScriptClient": {
"className": "{controller}Client",
"moduleName": "",
"namespace": "",
"typeScriptVersion": 4.3,
"template": "Angular",
"promiseType": "Promise",
"httpClass": "HttpClient",
"withCredentials": false,
"useSingletonProvider": true,
"injectionTokenType": "InjectionToken",
"rxJsVersion": 7.0,
"dateTimeType": "Date",
"nullValue": "Undefined",
"generateClientClasses": false,
"generateClientInterfaces": false,
"generateOptionalParameters": false,
"exportTypes": true,
"wrapDtoExceptions": false,
"exceptionClass": "ApiException",
"clientBaseClass": null,
"wrapResponses": false,
"wrapResponseMethods": [],
"generateResponseClasses": true,
"responseClass": "SwaggerResponse",
"protectedMethods": [],
"configurationClass": null,
"useTransformOptionsMethod": false,
"useTransformResultMethod": false,
"generateDtoTypes": true,
"operationGenerationMode": "MultipleClientsFromOperationId",
"markOptionalProperties": false,
"generateCloneMethod": false,
"typeStyle": "Interface",
"enumStyle": "Enum",
"useLeafType": false,
"classTypes": [],
"extendedClasses": [],
"extensionCode": null,
"generateDefaultValues": true,
"excludedTypeNames": [],
"excludedParameterNames": [],
"handleReferences": false,
"generateTypeCheckFunctions": false,
"generateConstructorInterface": true,
"convertConstructorInterfaceData": false,
"importRequiredTypes": true,
"useGetBaseUrlMethod": false,
"baseUrlTokenName": "API_BASE_URL",
"queryNullValue": "",
"useAbortSignal": false,
"inlineNamedDictionaries": true,
"inlineNamedAny": true,
"includeHttpContext": true,
"templateDirectory": null,
"serviceHost": null,
"serviceSchemes": null,
"output": "test.ts",
"newLineBehavior": "Auto"
}
}
}
然后,我按照说明将以下行添加到 Bets.WebUI.csproj 文件中:
<Target Name="NSwag" AfterTargets="Build">
<Exec Command="$(NSwagExe_Net70) run nswag.json /variables:Configuration=$(Configuration)" />
</Target>
但是,在项目构建过程中,进程在显示以下消息后挂起:
13>NSwag command line tool for .NET Core Net70, toolchain v14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))
13>Visit http://NSwag.org for more information.
13>NSwag bin directory: C:\Users\famou\.nuget\packages\nswag.msbuild\14.0.3\tools\Net70
13>
13>Executing file 'nswag.json' with variables 'Configuration=Debug'...
并且它不会进一步进行。
在这里提出问题之前,我研究了许多关于这个主题的指南。然而,没有什么可以帮助我。到处都有使用旧版本 .NET 和 NSwag 的文章。回滚版本不是一个选择;我想用最新的来弄清楚。
我还观看了视频“NSwag - SWAGGER For ASP.NET CORE 和 AUTOMATIC Type Generation For TypeScript”(https://www.youtube.com/watch?v=3UlCaK9iJaI)。在其中,作者建议对 aspNetCoreToOpenApi 进行这样的设置:
"aspNetCoreToOpenApi": {
"project": null,
"documentName": "v1",
"msBuildProjectExtensionsPath": null,
"configuration": null,
"runtime": null,
"targetFramework": null,
"noBuild": false,
"msBuildOutputPath": null,
"verbose": true,
"workingDirectory": null,
"aspNetCoreEnvironment": null,
"output": null,
"newLineBehavior": "Auto",
"assemblyPaths": [
"bin/Debug/net7.0/Bets.WebUI.dll"
],
"assemblyConfig": null,
"referencePaths": [],
"useNuGetCache": false
}
我也尝试过,但是在构建时,NSwag 只是删除了这些行并返回错误,指出未指定项目路径。
解决方案出奇地简单。
我首先研究了
aspNetCoreToOpenApi
部分中每个参数的功能。
我注意到了
noBuild
参数并决定更改其值以进行测试:
"noBuild": true,
进行此调整后,一切开始工作。
我第二天才注意到这一点,这让我觉得我昨天太累了,没有注意到。