jsonopenapinswag

How to generate the openapi.json with nswag


I am using nswag to generate the swagger. However the openapi json file is only in memory, you can only access it by starting the application and navigate to the link swagger/v1/swagger.json.

I want the json file to be generated and save physically in the project after every build. How should I achieved this?


Solution

  • i created a hosted service which executes my custom method to generate and save the api file in the project folder

            public static async Task GenerateOpenApiDoc(IServiceProvider services, string contentRootPath)
            {
    #if DEBUG
                int oldvalue = Interlocked.CompareExchange(ref _executed, 1, 0);
                if (oldvalue == 1)
                {
                    return;
                }
    
                string GetProjectDir()
                {
                    string contentRoot = contentRootPath;
                    string assemblyName = Assembly.GetEntryAssembly().GetName().Name;
                    string projName = $"{assemblyName}.csproj";
                    while (true)
                    {
                        if (string.IsNullOrEmpty(contentRoot))
                        {
                            return null;
                        }
    
                        if (!Directory.Exists(contentRoot))
                        {
                            return null;
                        }
    
                        string projPath = Path.Combine(contentRoot, projName);
                        if (File.Exists(projPath))
                        {
                            return Path.GetDirectoryName(projPath);
                        }
                        contentRoot = Directory.GetParent(contentRoot)?.FullName;
                    }
                }
    
                await Task.Run(async () =>
                {
                    using (var serviceScope = services.GetService<IServiceScopeFactory>()!.CreateScope())
                    {
                        IServiceProvider serviceProvider = serviceScope.ServiceProvider;
                        var options = serviceProvider.GetService<IOptions<SwaggerOptions>>();
                        string documentName = options.Value.Name;
                        var documentProvider = serviceProvider.GetService<NSwag.Generation.IOpenApiDocumentGenerator>() ?? throw new InvalidOperationException("The NSwag DI services are not registered: Call AddSwaggerDocument() in ConfigureServices().");
                        NSwag.OpenApiDocument apidoc = await documentProvider.GenerateAsync(documentName);
                        string spec = apidoc.ToJson();
                        string path = GetProjectDir();
                        string assemblyName = Assembly.GetEntryAssembly().GetName().Name;
                        if (string.IsNullOrEmpty(path))
                        {
                            throw new InvalidOperationException($"Failed to get project directory path for {assemblyName}");
                        }
                        string filePath = Path.Combine(path, $"{assemblyName}.json");
                        File.WriteAllText(filePath, spec);
                    }
                });
    
    #else
                await Task.CompletedTask;
    #endif
            }