In this post, we will see some tips that can help us when we use Swagger.
First of all, we open Visual Studio, we create a Web API project and add some files:
[BOOK.CS]
namespace TestSwagger.Model
{
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int Pages { get; set; }
public decimal Price { get; set; }
}
}
[BOOKCONTROLLER.CS]
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using TestSwagger.Model;
namespace TestSwagger.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class BookController : ControllerBase
{
List<Book> lstBooks = null;
public BookController()
{
lstBooks = new List<Book>();
lstBooks.Add(new Book { Id = 1, Author = "Author1", Pages = 100, Price = 12, Title = "Title1" });
lstBooks.Add(new Book { Id = 2, Author = "Author2", Pages = 140, Price = 20, Title = "Title2" });
lstBooks.Add(new Book { Id = 3, Author = "Author3", Pages = 200, Price = 32, Title = "Title3" });
lstBooks.Add(new Book { Id = 4, Author = "Author4", Pages = 800, Price = 45, Title = "Title4" });
lstBooks.Add(new Book { Id = 5, Author = "Author5", Pages = 70, Price = 12, Title = "Title5" });
lstBooks.Add(new Book { Id = 6, Author = "Author6", Pages = 170, Price = 9, Title = "Title5" });
}
[HttpGet]
public ActionResult<List<Book>> GetBooks()
{
return Ok(lstBooks);
}
[HttpGet("{Id}")]
public ActionResult<Book> GetBook(int Id)
{
var objBook = lstBooks.Where(x => x.Id == Id).SingleOrDefault();
if (objBook == null)
{
return NotFound();
}
return Ok(objBook);
}
[HttpPost]
public ActionResult InsertBook([FromBody] Book inputBook)
{
lstBooks.Add(inputBook);
return Ok();
}
}
}
If we run the application, this will be the result:
Now, we install the Swashbuckle.AspNetCore package, using the command Install-Package Swashbuckle.AspNetCore -Version 5.5.1 in the Package Manager Console and then, we will modify the Startup file in order to enable Swagger in our project:
[STARTUP.CS]
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
namespace TestSwagger
{
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.AddControllers();
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v. 1.0.0",
Title = "Book API",
Description = "Web API to manage Book"
});
});
}
// 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.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Book API");
});
}
}
}
Now, if we run the application, this will be the result:
Everything works and now, we will see some interesting tips:
ADD XML COMMENTS
In order to add a comment for every single functionalities and for every parameters, we modify the file BookController.cs:
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using TestSwagger.Model;
namespace TestSwagger.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class BookController : ControllerBase
{
List<Book> lstBooks = null;
public BookController()
{
lstBooks = new List<Book>();
lstBooks.Add(new Book { Id = 1, Author = "Author1", Pages = 100, Price = 12, Title = "Title1" });
lstBooks.Add(new Book { Id = 2, Author = "Author2", Pages = 140, Price = 20, Title = "Title2" });
lstBooks.Add(new Book { Id = 3, Author = "Author3", Pages = 200, Price = 32, Title = "Title3" });
lstBooks.Add(new Book { Id = 4, Author = "Author4", Pages = 800, Price = 45, Title = "Title4" });
lstBooks.Add(new Book { Id = 5, Author = "Author5", Pages = 70, Price = 12, Title = "Title5" });
lstBooks.Add(new Book { Id = 6, Author = "Author6", Pages = 170, Price = 9, Title = "Title5" });
}
/// <summary>
/// List of all Books
/// </summary>
/// <returns>[Books]</returns>
[HttpGet]
public ActionResult<List<Book>> GetBooks()
{
return Ok(lstBooks);
}
/// <summary>
/// Get a book by Id.
/// </summary>
/// <param name="Id">The id of the book you want to get</param>
/// <returns></returns>
[HttpGet("{Id}")]
public ActionResult<Book> GetBook(int Id)
{
var objBook = lstBooks.Where(x => x.Id == Id).SingleOrDefault();
if (objBook == null)
{
return NotFound();
}
return Ok(objBook);
}
/// <summary>
/// Save a new book.
/// </summary>
/// <param name="inputBook">From Body a new book</param>
/// <returns></returns>
[HttpPost]
public ActionResult InsertBook([FromBody] Book inputBook)
{
lstBooks.Add(inputBook);
return Ok();
}
}
}
Then, in order to force the application to generate the XML file data used by Swagger, we right click on the project, select Properties, select “Build” on the left hand side and finally we tick the checkbox “Xml documentation file”.
Finally, we modify the method ConfigureServices in the Startup file:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v. 1.0.0",
Title = "Book API",
Description = "Web API to manage Book"
});
c.IncludeXmlComments(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "TestSwagger.xml"));
});
}
Now, if we run the application this will be the result:
DESCRIBING API RESPONSE
In order to add a description for every response of the GetBook method, we modify again the file BookController.cs:
/// <summary>
/// Get a book by Id.
/// </summary>
/// <param name="Id">The id of the book you want to get</param>
/// <returns></returns>
/// <response code="200">Book returned</response>
/// <response code="404">Id not valid</response>
[ProducesResponseType(typeof(Book), 200)]
[ProducesResponseType(404)]
[HttpGet("{Id}")]
public ActionResult<Book> GetBook(int Id)
{
var objBook = lstBooks.Where(x => x.Id == Id).SingleOrDefault();
if (objBook == null)
{
return NotFound();
}
return Ok(objBook);
}
Now, if we run the application this will be the result:
CUSTOMIZE SWAGGER UI
In order to hide the Swagger logo and insert a new logo or a text in the Swagger UI, we have to create a file css called custom.css in a directory “wwwroot/swagger-ui” of our project :
.topbar-wrapper img[alt="Swagger UI"], .topbar-wrapper span {
visibility: hidden;
}
.topbar-wrapper .link:after {
content: 'Book API by Damiano';
color: #fff;
visibility: visible;
display: block;
position: absolute;
padding: 15px;
}
Then, we have to modify the method Configure in the file Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseStaticFiles();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Book API");
c.InjectStylesheet("/swagger-ui/custom.css");
});
}
Now, if we run the application this will be the result: