Introduction
Imagine you have built an ASP.NET Core Web API that several applications depend on. Your mobile app uses it to retrieve customer details, your website uses it to display orders, and another service uses it to process payments.
Everything works fine until you need to change the API response. Perhaps you want to rename a property, remove an old field, or change how an endpoint accepts data.
If you make these changes directly, existing applications may stop working. Updating every client at the same time is not always possible, especially when different teams maintain different applications.
This is where API versioning becomes useful.
API versioning allows you to introduce changes without immediately breaking existing clients. You can keep the current API available while developing a newer version with updated behavior.
In this article, we will learn how to add API versioning to an ASP.NET Core Web API, create separate versions of an endpoint, and handle common problems when using versioning in a real application.
What Is API Versioning?
API versioning is a way to maintain multiple versions of an API so that clients can continue using the version they depend on.
For example, consider an API that returns customer information.
Version 1 might return the customer's full name in a single property:
{
"id": 101,
"fullName": "Rahul Sharma"
}Later, you may want to return the first and last names separately.
{
"id": 101,
"firstName": "Rahul",
"lastName": "Sharma"
}If you change the existing response without considering current clients, applications expecting fullName may fail.
With API versioning, you can keep the original response available in version 1 and introduce the new response in version 2.
This gives clients time to migrate without forcing every application to update immediately.
Why Do You Need API Versioning?
API versioning is particularly useful when an API is shared across multiple applications or teams.
Here are some common situations where it helps:
- You need to change the structure of a response.
- You want to remove an old property or endpoint.
- You need to introduce new request parameters.
- Different clients need different API behavior.
- You want to introduce breaking changes without disrupting existing integrations.
Not every API change requires a new version. Adding an optional response field, for example, may be compatible with existing clients. The decision depends on how clients consume the API and the compatibility guarantees you provide.
Step 1: Create an ASP.NET Core Web API
Start by creating an ASP.NET Core Web API project using your preferred development environment.
You can create a project from the command line:
dotnet new webapi -n VersionedApi
cd VersionedApiNext, install the API versioning packages.
For controller-based APIs, install the following packages:
dotnet add package Asp.Versioning.Mvc
dotnet add package Asp.Versioning.Mvc.ApiExplorerThe first package provides API versioning support for MVC controllers. The second integrates version information with API Explorer, which is useful for generating version-specific API documentation.
Use package versions compatible with your target .NET framework and the other dependencies in your project.
Step 2: Configure API Versioning
Open Program.cs and register API versioning services.
In this example, we will use URL path versioning, where the version appears in the request URL.
using Asp.Versioning;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services
.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = false;
options.ReportApiVersions = true;
options.ApiVersionReader =
new UrlSegmentApiVersionReader();
})
.AddMvc()
.AddApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
var app = builder.Build();
app.UseHttpsRedirection();
app.MapControllers();
app.Run();Let's look at the important settings.
DefaultApiVersion defines the default version value used by the versioning system.
AssumeDefaultVersionWhenUnspecified is set to false so clients must provide a version instead of silently receiving the default version.
ReportApiVersions enables response headers that report supported and deprecated API versions where applicable.
UrlSegmentApiVersionReader tells ASP.NET Core to read the version from the URL path.
For example:
/api/v1/products
/api/v2/productsThe API Explorer configuration helps organize endpoints by version when you integrate a compatible OpenAPI or Swagger setup.
Step 3: Create a Versioned Controller
Now, create a controller that supports version 1.
Create a file named ProductsController.cs.
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
namespace VersionedApi.Controllers;
[ApiController]
[ApiVersion(1.0)]
[Route("api/v{version:apiVersion}/products")]
public class ProductsV1Controller : ControllerBase
{
[HttpGet]
public IActionResult GetProducts()
{
var products = new[]
{
new
{
Id = 1,
Name = "Laptop",
Price = 75000
},
new
{
Id = 2,
Name = "Keyboard",
Price = 2500
}
};
return Ok(products);
}
}The [ApiVersion(1.0)] attribute identifies the version supported by this controller.
The route contains v{version:apiVersion}, which allows the API versioning system to recognize the version segment in the URL.
When a client sends a GET request to /api/v1/products, the version 1 controller handles the request.
The example uses sample data to keep the focus on versioning. In a real application, you would usually retrieve products through a service or database.
Step 4: Add Version 2 of the API
Suppose you need to change the product response. Version 1 returns Name, while version 2 should return ProductName and include an availability status.
You can create a separate controller for version 2.
Jasen FiciPosted Oct 27, 2026, 12:15 PM
Nice write-up. It's in today's DotNetNews: https://dotnetnews.beehiiv.com/p/new-post-a2d3