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.
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.
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.
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.
This is the first in a series of success & fail posts. Now that the “eye candy” is sorted I can go back to coding.





