The purpose of this article is to show in very simple step how to add Swagger to your ASP.NET core project, targeting netcoreapp3.1

Table of content

Prerequisites

Why Swagger?

I’m a developer, why have I to write documentation? I’ve no time for it!

How can I test my API quickly?

Basically swagger answer you to this two questions: with swagger you have a ready-to-go tech documentation you can share with your teammate and give you a simple, intuitive and easy tool to test your REST API without external tools line insomnia rest client, postman, fiddler, an so on..

There is only a few thing you have to keep in mind:

  • Swagger is no “auto-magic”: he isn’t able to read your mind and guess out what a method or a property means, so you have to write documentation.
    But this is tech documentation, so you simple have to document your code with XML documentation. Between you and me… it’s not a big deal!
    For example:
namespace AspNetCoreJWT.Dto
{
    /// <summary>
    /// simple user DTO
    /// </summary>
    public class UserLogin
    {
        /// <summary>
        /// username
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// password
        /// </summary>
        public string Password { get; set; }
    }
}
  • As I said, is a tool useful for tech documentation, so shouldn’t use in production environment, because is a well know standard tool, is easy to find and expose all your API to a potentially indesiderate people.

Add swagger to project

  1. Go to NuGet package management and add Swashbuckle.AspNetCore
  2. if your are targeting your project to <TargetFramework>netcoreapp3.1</TargetFramework>, there is an incompatibility issue with Microsoft.AspNetCore.Mvc.MvcJsonOption dll.
    To fix it, you have to use a release candidate Swashbuckle version: 5.0.0-rc2
    In order to use it, you have to edit your csproj file and add/change Swashbuckle.AspNetCore package reference with: <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc2" />
    refer this: https://stackoverflow.com/questions/58084294/issues-with-swagger-after-migrating-to-net-core-3-0, if you want more information
  3. Enable DEBUG pre-compilation flag:
    1. go to project property
    2. look for: Define DEBUG constant, and flag it
  1. Enable xml documentation generation:go to project property
    1. look for “XML documentation file”, and flag it
    2. configure output location as: .\bin\Debug\netcoreapp3.1\ASP.NET-Core.xml
XML documentation file
  1. create new static class RegisterSwagger.cs, like this:
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.Collections.Generic;

namespace ASPNETCore
{
    /// <summary>
    /// used to add Swagger to project
    /// </summary>
    public static class RegisterSwagger
    {
        /// <summary>
        /// Configure JWT. use in <seealso cref="Startup.ConfigureServices(IServiceCollection)"/>
        /// </summary>
        /// <param name="self"></param>
        public static void ConfigureSwaggerService(this IServiceCollection self)
        {
#if DEBUG
            // Register the Swagger generator, defining 1 or more Swagger documents
            self.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = "ASPNETCore API",
                    Version = "v1",
                    Description = "Full documentation to ASPNETCore public API",
                    Contact = new OpenApiContact
                    {
                        Name = "Zoccarato Davide",
                        Email = "davide@davidezoccarato.cloud",
                        Url = new Uri("https://www.davidezoccarato.cloud/")
                    },
                });

#pragma warning disable CS0618 // Type or member is obsolete
                c.DescribeAllEnumsAsStrings();
#pragma warning restore CS0618 // Type or member is obsolete

                c.IncludeXmlComments(string.Format(@"{0}\ASP.NET-Core.xml", System.AppDomain.CurrentDomain.BaseDirectory));
                c.IgnoreObsoleteProperties();

                // ref: https://stackoverflow.com/questions/56234504/migrating-to-swashbuckle-aspnetcore-version-5
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "Bearer"
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            },
                            Scheme = "oauth2",
                            Name = "Bearer",
                            In = ParameterLocation.Header,

                        },
                        new List<string>()
                    }
                });

            });
#endif
        }

        /// <summary>
        /// Configure Swagger. use in <seealso cref="Startup.Configure(IApplicationBuilder, Microsoft.AspNetCore.Hosting.IWebHostEnvironment)"/>
        /// </summary>
        /// <param name="self"></param>
        public static void ConfigureSwagger(this IApplicationBuilder self)
        {
#if DEBUG
            // Enable middleware to serve generated Swagger as a JSON endpoint.
            self.UseSwagger();

            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), 
            // specifying the Swagger JSON endpoint.
            self.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "ASPNETCore API V1");
                c.RoutePrefix = "swagger/ui";
            });
#endif
        }
    }
}
  1. add swagger to Startup
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    services.AddTransient<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>()?.HttpContext?.User);

    //
    services.ConfigureSwaggerService();
    services.ConfigureJWTService(Configuration);
    services.ConfigureAppServices(Configuration);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();
            
    app.ConfigureJWT();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    app.ConfigureSwagger();
}

Run Swagger

  1. Run your project in debug mode
  2. Open a browser and go to ” https://localhost:5001/swagger/ui/index.html
  3. You should have a page like this:
https://localhost:5001/swagger/ui/index.html
  1. In order to authorize the API, you must authenticate.
    to do that you have to put you Bearer token to “Authorize” button on top-right corner
    1. Expand Login API
    2. click on “Try it out” button (), this will “unlock” the editing
    3. Edit json field with username / password
    4. Click “execute”
    5. On “Response body” section you’ll get your JWT token
    6. Copy token content and use to compose you Authentication http header as:
      Bearer {token_content}
    7. Click con “Authorize” button on top-right corner
    8. Put the result string coming form point 6 to Authorize form
4.5
  1. After that, you are authenticated and you are able to test your API
5

Show in a gif

swagger in a gif

open in a new windows

Hint

If you prefer, you can launch swagger automatically when you run your project.
In order to do that, you have to edit launchSettings.json file and add something like that:

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:51237",
      "sslPort": 44395
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger/ui/index.html",
      "applicationUrl": "https://localhost:5001",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "ASP.NET-Core": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger/ui/index.html",
      "applicationUrl": "https://localhost:5001",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Looking in the deep

c.SwaggerDoc("v1", new OpenApiInfo
{
    Title = "ASPNETCore API",
    Version = "v1",
    Description = "Full documentation to ASPNETCore public API",
    Contact = new OpenApiContact
    {
        Name = "Zoccarato Davide",
        Email = "davide@davidezoccarato.cloud",
        Url = new Uri("https://www.davidezoccarato.cloud/")
    },
});

Define one or more documents to be created by the Swagger generator with basic information that use OpenApi standard ( https://github.com/microsoft/OpenAPI.NET/blob/master/src/Microsoft.OpenApi/Models/OpenApiInfo.cs)

c.IncludeXmlComments(string.Format(@"{0}\ASP.NET-Core.xml", System.AppDomain.CurrentDomain.BaseDirectory));

This allow you to add XML documentation on Swagger generated documentation. Make sure the given path match with what you have configured on project setting.

c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
    Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
    Name = "Authorization",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.ApiKey,
    Scheme = "Bearer"
});

c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
    {
        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference
            {
                Type = ReferenceType.SecurityScheme,
                Id = "Bearer"
            },
            Scheme = "oauth2",
            Name = "Bearer",
            In = ParameterLocation.Header,

        },
        new List<string>()
    }
});

This allows you to use JWT token to autenticate the API.
Also this is using OpenApi standard

#if DEBUG
// some code here
// some code here
// some code here
// some code here
// some code here
#endif

This allows you to add Swagger only if DEBUG compilation flag is enabled.
Prevent indesiderate exposing of your api to all people.

Source Code

Leave a Comment