Swagger needs no introduction. It is one of the best methods to test your WEB APIs. Adding swagger to your ASP.NET Core application is very easy and straightforward. I already have a couple of posts on my blog on Swagger. Swagger comes with many options and customization to help you prepare better API documentation. The ASP.NET Core Startup.cs
is the place to add Swagger or any middleware that you would like to use in your ASP.NET Core application. The Startup.cs file will become lengthy when we use more swagger customization. So in this post, we’ll see a clean way to add Swagger to ASP.NET Core application using C# extension methods.
A clean way to add Swagger to ASP.NET Core application
Just to refresh your memory, you need to install Swashbuckle.AspNetCore
nuget package which comprises of – a Swagger generator, middleware to expose the generated Swagger as JSON endpoints and middleware to expose a swagger-ui that’s powered by those endpoints. Once the package is installed, the minimum code required to configure swagger in the Startup.cs
would be:
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
Here, the code to configure swagger is very minimal. But in real projects, it will be more than this. Here, look at the sample Startup.cs
file from one of my ASP.NET Core application. This swagger code can grow if more customization is done.
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "My API", Description = "My First ASP.NET Core Web API", TermsOfService = new System.Uri("www.talkingdotnet.com"), Contact = new OpenApiContact() { Name = "Talking Dotnet", Email = "contact@talkingdotnet.com" } }); c.SwaggerDoc("v2", new OpenApiInfo { Version = "v2", Title = "New API V2", Description = "Sample Web API", TermsOfService = new System.Uri("www.talkingdotnet.com"), Contact = new OpenApiContact() { Name = "Talking Dotnet", Email = "contact@talkingdotnet.com" } }); c.DescribeAllEnumsAsStrings(); c.DescribeStringEnumsInCamelCase(); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); c.SwaggerEndpoint("/swagger/v2/swagger.json", "My API V2"); }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
ASP.NET Core startup file configures the request pipeline, contains all the middleware, services, policies and options to configure. In large applications, this could result in hundreds of lines of code. But, there is a way to clean this mess and make Startup.cs more readable and manageable.
We can leverage C# extension methods to create extension methods for IApplicationBuilder
or IServiceCollection
. An extension method is actually a special kind of static method defined in a static class. To define an extension method,
Here is our SwaggerExtension
class.
public static class SwaggerExtension { public static void AddSwagger(this IServiceCollection services) { services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "My API", Description = "My First ASP.NET Core Web API", TermsOfService = new System.Uri("https://www.talkingdotnet.com"), Contact = new OpenApiContact() { Name = "Talking Dotnet", Email = "contact@talkingdotnet.com" } }); c.SwaggerDoc("v2", new OpenApiInfo { Version = "v2", Title = "New API V2", Description = "Sample Web API", TermsOfService = new System.Uri("https://www.talkingdotnet.com"), Contact = new OpenApiContact() { Name = "Talking Dotnet", Email = "contact@talkingdotnet.com" } }); c.DescribeAllEnumsAsStrings(); c.DescribeStringEnumsInCamelCase(); }); } public static void UseCustomSwagger(this IApplicationBuilder app) { app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); c.SwaggerEndpoint("/swagger/v2/swagger.json", "My API V2"); }); } }
There are 2 extension methods defined respectively for IServiceCollection
and IApplicationBuilder
. You can now call the extension methods in the Startup.cs
class. Like,
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwagger(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseCustomSwagger(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
That’s it.
Summary
To summarize, using extension methods, we can make the Startup.cs
clean and readable. We should create extension methods for each service added to the IServiceCollection
and IApplicationBuilder
in separate files. This will help in code reusability and also make code manageable.
Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.
Fetch error undefined /swagger/v1/swagger.json
i am getting this error
Please help. i am using core 3.2
swagger will not work in 3.x version.
Fetch error undefined /swagger/v1/swagger.json
i am getting this error
Is there a sample code also ?