ASP.NET Core - Swashbuckle not creating swagger.json file
I believe you missed these two lines on your Configure:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "MyAPI V1");
});
}
To access Swagger UI, the URL should be: http://localhost:XXXX/swagger/
The json can be found at the top of Swagger UI:
Why swagger.json gets not found error when hosted as an application under a website on IIS?
For swagger.json
, you need to append the website before the SwaggerEndpoint
like c.SwaggerEndpoint("/mysite/swagger/v1/swagger.json", "My API V1");
. As you have found, your swagger.json is exist under http://localhost/mysite/swagger/v1/swagger.json
instead of http://localhost/swagger/v1/swagger.json
.
Try to change your configuration like
app.UseSwaggerUI(c =>
{
#if DEBUG
// For Debug in Kestrel
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Web API V1");
#else
// To deploy on IIS
c.SwaggerEndpoint("/mysite/swagger/v1/swagger.json", "Web API V1");
#endif
c.RoutePrefix = string.Empty;
});
ASP.NET Core - Swashbuckle not creating swagger.json file
I believe you missed these two lines on your Configure:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "MyAPI V1");
});
}
To access Swagger UI, the URL should be: http://localhost:XXXX/swagger/
The json can be found at the top of Swagger UI:
Swashbuckle Error - 404 for 'swagger.json' when running in IIS
Regarding your case, you can do this to configure your Swagger
for IIS:
options.SwaggerEndpoint($"../swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
AspNetCore Swagger for JSON and UI endpoints returning 404
I figured the issue, quite obscure if you ask me. Anyway, this StackOverflow answer helped me and was basically my issue.
When adding your SwaggerGen
, the first parameter name
setupAction.SwaggerDoc(
"Open API Specification for Haros v1", //... etc
)
slots into the URL for the generated documentation at the middleware part here:
setupAction.SwaggerEndpoint("/swagger/<from swagger doc name parameter>/swagger.json", "Haros API v1");
If you do this:
setupAction.SwaggerDoc(
"v1", //... etc
)
And doing this:
setupAction.SwaggerEndpoint("/swagger/v1/swagger.json", "Haros API v1");
Swagger will load successfully on both endpoints (https://localhost:5001/swagger/index.html
and https://localhost:5001/swagger/v1/swagger.json
)
SWAGGER UI does not show up - Swagger.json does on .NET Core
I have test you method both in .Net5 and .Net core2.1 project, and it works fine.
Tips: And pls change swagger sentence from env.IsDevelopment to outsite. This is where it's easy to overlook.
.Net 5.0
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Server.HttpSys;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using webapi.Middleware;
using System.Reflection;
using Swashbuckle.AspNetCore.SwaggerGen;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
namespace webapi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//services.AddApplicationInsightsTelemetry();
services.AddLogging();
services.AddControllers().AddNewtonsoftJson();
services.AddApiVersioning(
options =>
{
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
options.ReportApiVersions = true;
});
services.AddVersionedApiExplorer(
options =>
{
// add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
// note: the specified format code will format the version as "'v'major[.minor][-status]"
options.GroupNameFormat = "'v'VVV";
// note: this option is only necessary when versioning by url segment. the SubstitutionFormat
// can also be used to control the format of the API version in route templates
options.SubstituteApiVersionInUrl = true;
});
services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
if (this.Configuration["EnableSwagger"] == "true")
{
//services.AddSwaggerGen(opt =>
//opt.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
//// Set the comments path for the Swagger JSON and UI.
//var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
//var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
//opt.IncludeXmlComments(xmlPath);
services.AddSwaggerGen(opt =>
{
opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme."
});
opt.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
}
services.AddDistributedMemoryCache();
services.AddSession();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
IApiVersionDescriptionProvider provider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(o => o.GroupName))
{
c.SwaggerEndpoint(
$"/swagger/{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
//app.UseCustomMiddleware();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
readonly IApiVersionDescriptionProvider _apiVerProvider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider apiVerProvider) => _apiVerProvider = apiVerProvider;
public void Configure(SwaggerGenOptions options)
{
foreach (var description in _apiVerProvider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName, GetSwaggerDocInfo(description));
}
}
static OpenApiInfo GetSwaggerDocInfo(ApiVersionDescription description)
{
var info = new OpenApiInfo
{
Title = $"WebAPI {description.ApiVersion}",
Version = description.GroupName,
Description = "Web API Template",
Contact = new OpenApiContact()
{
Name = "Web API service"
},
License = new OpenApiLicense()
{
Name = "MIT"
}
};
if (description.IsDeprecated)
{
info.Description += $" {description.ApiVersion} API version is deprecated.";
}
return info;
}
}
}
.Net 2.1
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Swagger21
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//services.AddApplicationInsightsTelemetry();
services.AddLogging();
services.AddMvcCore().AddVersionedApiExplorer();
services.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
if (this.Configuration["EnableSwagger"] == "true")
{
//services.AddSwaggerGen(opt =>
//opt.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
//// Set the comments path for the Swagger JSON and UI.
//var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
//var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
//opt.IncludeXmlComments(xmlPath);
services.AddSwaggerGen(opt =>
{
opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme."
});
opt.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
}
services.AddDistributedMemoryCache();
services.AddSession();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app , IHostingEnvironment env,
IApiVersionDescriptionProvider provider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(o => o.GroupName))
{
c.SwaggerEndpoint(
$"/swagger/{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
app.UseHttpsRedirection();
app.UseSession();
app.UseMvc();
}
}
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
readonly IApiVersionDescriptionProvider _apiVerProvider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider apiVerProvider) => _apiVerProvider = apiVerProvider;
public void Configure(SwaggerGenOptions options)
{
foreach (var description in _apiVerProvider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName, GetSwaggerDocInfo(description));
}
}
static OpenApiInfo GetSwaggerDocInfo(ApiVersionDescription description)
{
var info = new OpenApiInfo
{
Title = $"WebAPI {description.ApiVersion}",
Version = description.GroupName,
Description = "Web API Template",
Contact = new OpenApiContact()
{
Name = "Web API service"
},
License = new OpenApiLicense()
{
Name = "MIT"
}
};
if (description.IsDeprecated)
{
info.Description += $" {description.ApiVersion} API version is deprecated.";
}
return info;
}
}
}
SWAGGER UI does not show up - Swagger.json does on .NET Core
I have test you method both in .Net5 and .Net core2.1 project, and it works fine.
Tips: And pls change swagger sentence from env.IsDevelopment to outsite. This is where it's easy to overlook.
.Net 5.0
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Server.HttpSys;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using webapi.Middleware;
using System.Reflection;
using Swashbuckle.AspNetCore.SwaggerGen;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
namespace webapi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//services.AddApplicationInsightsTelemetry();
services.AddLogging();
services.AddControllers().AddNewtonsoftJson();
services.AddApiVersioning(
options =>
{
// reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
options.ReportApiVersions = true;
});
services.AddVersionedApiExplorer(
options =>
{
// add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
// note: the specified format code will format the version as "'v'major[.minor][-status]"
options.GroupNameFormat = "'v'VVV";
// note: this option is only necessary when versioning by url segment. the SubstitutionFormat
// can also be used to control the format of the API version in route templates
options.SubstituteApiVersionInUrl = true;
});
services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
if (this.Configuration["EnableSwagger"] == "true")
{
//services.AddSwaggerGen(opt =>
//opt.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
//// Set the comments path for the Swagger JSON and UI.
//var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
//var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
//opt.IncludeXmlComments(xmlPath);
services.AddSwaggerGen(opt =>
{
opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme."
});
opt.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
}
services.AddDistributedMemoryCache();
services.AddSession();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
IApiVersionDescriptionProvider provider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(o => o.GroupName))
{
c.SwaggerEndpoint(
$"/swagger/{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
//app.UseCustomMiddleware();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
readonly IApiVersionDescriptionProvider _apiVerProvider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider apiVerProvider) => _apiVerProvider = apiVerProvider;
public void Configure(SwaggerGenOptions options)
{
foreach (var description in _apiVerProvider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName, GetSwaggerDocInfo(description));
}
}
static OpenApiInfo GetSwaggerDocInfo(ApiVersionDescription description)
{
var info = new OpenApiInfo
{
Title = $"WebAPI {description.ApiVersion}",
Version = description.GroupName,
Description = "Web API Template",
Contact = new OpenApiContact()
{
Name = "Web API service"
},
License = new OpenApiLicense()
{
Name = "MIT"
}
};
if (description.IsDeprecated)
{
info.Description += $" {description.ApiVersion} API version is deprecated.";
}
return info;
}
}
}
.Net 2.1
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Swagger21
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//services.AddApplicationInsightsTelemetry();
services.AddLogging();
services.AddMvcCore().AddVersionedApiExplorer();
services.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
if (this.Configuration["EnableSwagger"] == "true")
{
//services.AddSwaggerGen(opt =>
//opt.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
//// Set the comments path for the Swagger JSON and UI.
//var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
//var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
//opt.IncludeXmlComments(xmlPath);
services.AddSwaggerGen(opt =>
{
opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme."
});
opt.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
}
services.AddDistributedMemoryCache();
services.AddSession();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app , IHostingEnvironment env,
IApiVersionDescriptionProvider provider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
foreach (var description in provider.ApiVersionDescriptions.OrderByDescending(o => o.GroupName))
{
c.SwaggerEndpoint(
$"/swagger/{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
app.UseHttpsRedirection();
app.UseSession();
app.UseMvc();
}
}
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
readonly IApiVersionDescriptionProvider _apiVerProvider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider apiVerProvider) => _apiVerProvider = apiVerProvider;
public void Configure(SwaggerGenOptions options)
{
foreach (var description in _apiVerProvider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName, GetSwaggerDocInfo(description));
}
}
static OpenApiInfo GetSwaggerDocInfo(ApiVersionDescription description)
{
var info = new OpenApiInfo
{
Title = $"WebAPI {description.ApiVersion}",
Version = description.GroupName,
Description = "Web API Template",
Contact = new OpenApiContact()
{
Name = "Web API service"
},
License = new OpenApiLicense()
{
Name = "MIT"
}
};
if (description.IsDeprecated)
{
info.Description += $" {description.ApiVersion} API version is deprecated.";
}
return info;
}
}
}
Related Topics
Removing Elements from Json Based on a Condition in C#
Cannot Access a Closed Stream of a Memorystream, How to Reopen
How to Get the Current Project Directory from C# Code When Creating a Custom Msbuild Task
Use Latest Version of Internet Explorer in the Webbrowser Control
Convert Json File to C# and Stored in Database
C# ASP.NET MVC Download a File Via Ajax
How to Iterate Though Each Child Node in an Xml File
Documentdb With Azure Functions
C# SQL Server Stored Procedure Parameter Return List
Calling a Function from Another Class in C#/.Net MVC App
How to Close a File That Is Already Opened in a Directory
How to Call a Button Click Event from Another Method
How to Remove Windows Credentials
Convert from Httpresponsemessage to Iactionresult in .Net Core
Ziparchive Gives Unexpected End of Data Corrupted Error
How to Print the Elements With Text Value That Contains in a List Selenium C#