Step-by-Step Guide to Web API Versioning with Multiple Versions, Swagger Support, and Exception Handling in .NET Core using C#
Web API versioning is crucial when developing and maintaining APIs to ensure seamless updates and backward compatibility with client applications. This article will explore how to implement Web API versioning in a .NET Core application using C#. Additionally, we will leverage the power of Swagger to provide documentation for each API version. Moreover, we will enhance our API by adding exception-handling capabilities.
Prerequisites
Before we begin, make sure you have the following installed on your machine:
- .NET Core SDK (6 or later)
- Visual Studio or Visual Studio Code (optional but recommended)
Step 1: Setting Up the Project
Let’s start by creating a new .NET Core Web API project. Open your terminal or command prompt and run the following command:
dotnet new webapi -n ApiVersioningWithSwagger
cd ApiVersioningWithSwagger
This command will create a new .NET Core Web API project named “ApiVersioningWithSwagger.”
Step 2: Install Required NuGet Packages
To enable versioning, Swagger support, and exception handling, we need to install the following NuGet packages:
dotnet add package Microsoft.AspNetCore.Mvc.Versioning
dotnet add package Swashbuckle.AspNetCore
Step 3: Configure Web API Versioning
Open the Program.cs
file, which is located in the root of your project, add the following code to configure API versioning:
using Microsoft.AspNetCore.Mvc;
//...
// Configure Web API Versioning
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
});
Step 4: Create API Controllers with Multiple Versions
Let’s create two versions of a sample API controller to demonstrate versioning. Create a new folder named “Controllers” at the root of your project. Inside this folder, add two files:
using Microsoft.AspNetCore.Mvc;
namespace ApiVersioningWithSwagger.Controllers.v1;
[ApiController]
[Route("api/v{version:apiVersion}/weatherforecast")]
[ApiVersion("1.0")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
v1 folder > WeatherForecastController.cs
using Microsoft.AspNetCore.Mvc;
namespace ApiVersioningWithSwagger.Controllers.v2;
[ApiController]
[Route("api/v{version:apiVersion}/weatherforecast")]
[ApiVersion("2.0")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
v2 folder > WeatherForecastController.cs
These two controllers represent versions 1.0 and 2.0 of the WeatherForecastController, each returning a different message in the response.
Step 5: Configure Swagger for API Documentation
Open the Program.cs
file, which is located in the root of your project, add the following code to enable Swagger documentation:
using Microsoft.AspNetCore.Mvc.Versioning;
// ...
// Configure Swagger for API Documentation
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "API V1", Version = "v1" });
c.SwaggerDoc("v2", new OpenApiInfo { Title = "API V2", Version = "v2" });
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
In this code snippet, we are configuring two Swagger documents, one for each API version.
Step 6: Include Versioned API Controllers in Swagger
Include versioned controllers in Swagger:
using Microsoft.AspNetCore.Mvc.Versioning;
// ...
// Include Versioned API Controllers in Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API V1");
c.SwaggerEndpoint("/swagger/v2/swagger.json", "API V2");
});
Step 7: Add Exception Handling
Now, let’s enhance our API by adding exception-handling capabilities. Open the Program.cs
file, which is located in the root of your project, add the following code to add an exception handler:
// ...
app.UseExceptionHandler("/error");
In this code snippet, we add an exception handler using the UseExceptionHandler
middleware. When an exception occurs in your API, it will be directed to the /error
endpoint.
Step 8: Create the Error Controller
Create a new folder named “Controllers” in the root of your project if it doesn’t exist. Inside this folder, add a new file named ErrorController.cs
:
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
namespace ApiVersioningWithSwagger.Controllers
{
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorController : ControllerBase
{
[Route("/error")]
public async Task<IActionResult> Error()
{
Exception? exception = HttpContext.Features.Get<IExceptionHandlerFeature>().Error;
await Task.CompletedTask;
return Problem(detail: exception.Message);
}
}
}
This controller handles exceptions and returns a problem details response with the exception message.
Step 9: Test the API
Build and run the application using the following command:
dotnet run
Open your browser and navigate to https://localhost:5001/swagger
. This will open the Swagger UI, showing the documentation for both API versions. You can explore and test the available endpoints directly from the Swagger UI.
Step 10: Test API Versioning
You can use a tool like Postman or the browser to test the API versioning.
For version 1.0, open a browser or use a tool like Postman and navigate to:
https://localhost:5001/api/v1/weatherforecast
For version 2.0, use the following URL:
https://localhost:5001/api/v2/weatherforecast
You should receive the corresponding messages from each version of the API.
Conclusion
This article covers how to implement Web API versioning in a .NET Core application using C#. We’ve also integrated Swagger to provide documentation for each API version. Additionally, we enhanced our API by adding exception-handling capabilities, allowing us to handle errors and gracefully provide meaningful responses to clients.
Following these steps, you have learned how to create a well-structured and versioned API while ensuring a smooth development and maintenance process. Incorporating exception handling further improves the reliability and user experience of your API.
Remember that proper versioning and exception handling are essential to a robust and user-friendly API. By mastering these techniques, you can confidently build efficient and resilient APIs. Happy coding!