.NET Core web API + Dapper – Swagger

This is the first post in a series about my “learning journey” integrating Swagger/OpenAPI into my WebAPI + Dapper sample….

In the first iteration, I extracted the Title, Description etc. from the Assembly Version information.

// Extract application info for Swagger docs from assembly info
var fileVersionInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location);

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1",
    new OpenApiInfo
    {
        Title = fileVersionInfo.ProductName,
        Version = $"{fileVersionInfo.FileMajorPart}.{fileVersionInfo.FileMinorPart}",
        Description = fileVersionInfo.Comments,

        License = new OpenApiLicense
        {
             Name = fileVersionInfo.LegalCopyright,
             //Url = new Uri(""),
        },
        //TermsOfService = new Uri(""),

        Contact = new OpenApiContact
        {
            Name = fileVersionInfo.CompanyName,
            //Url = new Uri(""),
        }
    });
    c.OperationFilter<AddResponseHeadersFilter>();
    c.IncludeXmlComments(string.Format(@"{0}\WebAPIDapper.xml", System.AppDomain.CurrentDomain.BaseDirectory));
});

This worked okay but there were still some fields which I had to manually update (or there was no matching property in the assembly information), so I abandoned this approach. I still use the version information property as this changes regularly as part of my build management process.

var version = Assembly.GetEntryAssembly().GetName().Version;

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1",
    new OpenApiInfo
    {
        Title = ".NET Core web API + Dapper + Swagger",
        Version = $"{version.Major}.{version.Minor}",

        Description = "This sample application shows how .NET Core and Dapper can be used to build lightweight Web APIs described with Swagger",
        Contact = new()
        {
            //Email = "", // Not certain this is a good idea
            Name = "Bryn Lewis",
            Url = new Uri("https://blog.devMobile.co.nz")
        },
        License = new()
        {
            Name = "MIT License",
            Url = new Uri("https://opensource.org/licenses/MIT"),
        }
    });
    c.OperationFilter<AddResponseHeadersFilter>();
    c.IncludeXmlComments(string.Format(@"{0}\WebAPIDapper.xml", System.AppDomain.CurrentDomain.BaseDirectory));
});

I then updated the builder.Services.AddSwaggerGen parameters to include the XML documentation comments but the application failed with an exception when I started it up.

Application failed because of missing XML docs file
Enabling the Generation of XML Documentation file

I wanted my Swagger Interface Definition to have a Favicon. I used Favicon Generator which generates a zip file containing different resolution versions of Shaun The Sheep.

The first time I tried to edit one of the image files the “this file comes from and untrusted source..” warning was displayed.

Using File Properties to unblock contents.

I “unblocked” the downloaded zip file and extracted the contents again rather than having to unblock each file individually. I then launched the website in the Visual Studio 2002 debugger and the favicon was not displayed. I had forgotten to configure copying of the image files when the application was compiled.

Configuring the favicon images to be copied to the website root.

I added some javascript to display the favicon on the top of the browser toolbar as well.

(function () {
    var link = document.querySelector("link[rel*='icon']") || document.createElement('link');;
    document.head.removeChild(link);
    link = document.querySelector("link[rel*='icon']") || document.createElement('link');
    document.head.removeChild(link);
    link = document.createElement('link');
    link.type = 'image/x-icon';
    link.rel = 'shortcut icon';
    link.href = '../images/favicon.ico';
    document.getElementsByTagName('head')[0].appendChild(link);
})();

I used my “elite” Cascading Style Sheet(CSS) skills to change the colour of the Swagger API explorer toolbar to light blue

.swagger-ui .topbar {
    background-color:lightblue    
}

Neither of these “enhancements” worked first time as I had neglected to configure the loading of static files.

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "css")),
    RequestPath = "/css",
});

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "images")),
    RequestPath = "/images",
});

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "JavaScript")),
    RequestPath = "/JavaScript",
});

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();

    app.UseSwaggerUI(c =>
    {
        c.EnableFilter();
        c.InjectStylesheet("/css/Swagger.css");
        c.InjectJavascript("/JavaScript/Swagger.js");
        c.DocumentTitle = "Web API Dapper Sample";
        });
    }
}

Now the Swagger Docs interface is a “visual symphony” with customisations illustrating the options available.

Swager API Explorer with custom images and “elite” styling

This is the first in a series of success & fail posts. Now that the “eye candy” is sorted I can go back to coding.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.