How to Implement API Versioning in ASP.NET Core Web API

Coding DropletsCoding Droplets
7 min read

Introduction

When building and maintaining APIs, especially in enterprise applications, changes over time are inevitable. One of the most efficient ways to handle these changes without breaking existing client applications is by implementing API versioning.

In this tutorial, we’ll walk you through step-by-step on how to implement ASP.NET Core API versioning in a real-world project. Whether you're a junior developer just getting started or someone looking to follow API versioning best practices in .NET Core, this guide is for you.

💡
Full source code is available on our Patreon. Get access and follow along!

🚀 What Is API Versioning?

API versioning allows developers to manage changes to their API in a way that doesn’t disrupt existing consumers. With ASP.NET Core Web API versioning, we can evolve our APIs over time, offering new features while keeping older versions operational.

🛠️ Setting Up Versioning in ASP.NET Core

To begin with dotnet core API versioning, we first need to install some important packages:

dotnet add package Asp.Versioning.Mvc
dotnet add package Asp.Versioning.Mvc.ApiExplorer

These libraries are part of the official Microsoft.AspNetCore.Mvc.Versioning package family and provide everything needed for proper version management in ASP.NET Core APIs.

🧱 Structuring the Project

Assume we have a simple controller named WeatherForecastController. We'll begin by organizing our codebase in a scalable way.

  1. Create a folder named V1 and move the WeatherForecastController into it.

  2. Add the [ApiVersion(\"1.0\")] attribute to the controller.

  3. Update the route to include the version number:

[Route("api/v{version:apiVersion}/[controller]")]

Repeat this process to create V2 and V3 versions of the controller. Update their namespaces and version attributes accordingly. This ensures that each controller handles a specific version of the API.

This structure is a common API versioning best practice in .NET Core, as it clearly separates logic based on API version.

⚙️ Configure Versioning in Program.cs

Inside the Program.cs file, we now configure versioning:

builder.Services.AddApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.ReportApiVersions = true;
});

Here’s what each setting does:

  • AssumeDefaultVersionWhenUnspecified: Uses the default version if none is specified.

  • DefaultApiVersion: Sets the default to 1.0.

  • ReportApiVersions: Adds supported versions in the response headers.

These settings are crucial for a smooth .NET Core API versioning setup.

🧭 Enabling Version by Namespace Convention

Next, enable AddMvc and configure versioning by namespace:

VersionByNamespaceConvention allows us to version controllers based on their namespace.

builder.Services.AddApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.ReportApiVersions = true;
}).AddMvc(options =>
{
    options.Conventions.Add(new VersionByNamespaceConvention());
});

🔄 Alternative Ways to Specify API Version in ASP.NET Core

Up until now, we've been using the URL path to specify the API version - a common and straightforward approach in ASP.NET Core API versioning.

However, ASP.NET Core supports multiple strategies for versioning beyond the URL. These methods can make your API more flexible and align with different client preferences. Let’s explore them.

🛣️ Step 1: Add Route Template Without Version

To allow versioning through Non-URL methods, we first add an additional route template to our controllers that doesn't include the version number. For instance:

[Route("api/WeatherForecast")]

Apply this route across all versioned controllers (V1, V2, V3). This enables the endpoint to handle requests where the version isn’t defined in the URL.

⚙️ Step 2: Configure ApiVersionReader in Program.cs

To tell our application how to extract the API version, we configure an ApiVersionReader. This is a critical part of dotnet core API versioning and allows support for multiple versioning strategies.

Here’s how to set it up in Program.cs:

builder.Services.AddApiVersioning(options =>
{
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.ReportApiVersions = true;
    options.ApiVersionReader = ApiVersionReader.Combine(
        new QueryStringApiVersionReader("api-version"),
        new HeaderApiVersionReader("Api-Version"),
        new MediaTypeApiVersionReader("api-version"));
}).AddMvc(options =>
{
    options.Conventions.Add(new VersionByNamespaceConvention());
});

🧩 Supported API Versioning Methods in ASP.NET Core

Let’s take a closer look at the supported approaches:

  1. Query String Versioning
    Easily testable and beginner-friendly. Just append ?api-version=1.0 to the endpoint.

  2. Header-based Versioning
    Pass the version in the request header:

      x-api-version: 2.0
    
  3. Media Type Versioning
    Embed the version in the Content-Type or Accept header:

      application/json;api-version=3.0
    
  4. Combined Strategy
    The configuration above supports all three at once. This makes your ASP.NET Core Web API highly flexible and compatible with diverse client implementations, a best practice in modern API versioning in ASP.NET Core.

🔍 Testing Our Versioned API with Postman

You can now test different versions using tools like Postman:

  • URL versioning:
    GET /api/v1/weatherforecast
    GET /api/v2/weatherforecast

  • Query string versioning:
    GET /api/weatherforecast?api-version=2.0

  • Header-based versioning:
    Add api-version: 3.0 in headers.

  • Media type versioning:
    Set Content-Type to application/json;v=3.0.

By configuring ApiVersionReader, you can support all these methods at once, making your ASP.NET Core API flexible and user-friendly.

📘 Swagger Integration for API Versioning in ASP.NET Core

To make testing and documentation easier, we’ve also integrated Swagger into our demo project. Swagger is a powerful tool for visualizing and interacting with your ASP.NET Core Web API, especially when working with multiple API versions.

When properly configured, Swagger UI automatically displays all available API versions, along with their corresponding endpoints. This is particularly useful when managing API versioning in ASP.NET Core, as it helps developers quickly explore and test different versions without switching tools.

✅ What Swagger Provides

Here’s how Swagger enhances our dotnet core API versioning setup:

  • Lists each versioned API group (e.g., v1, v2, v3) in the UI.

  • Shows the available routes for every version.

  • Allows you to directly execute API calls with the selected version.

  • Automatically updates the URL when you switch between versions.

For instance, if you select v2 from the dropdown, Swagger updates the URL and sends the request to the v2 controller. The response will include a message confirming that Version 2 was executed - a great way to visually verify that your ASP.NET Core API versioning is working correctly.

📂 Access Full Swagger Configuration

If you'd like to dive deeper into the implementation, you can find all the Swagger configuration classes and examples in the Source Code provided on our Patreon.

🧑‍💻 Real-World Scenarios

Here’s how you might use versioning in production:

  • Version 1: Current live version used by existing clients.

  • Version 2: A new version introducing minor changes.

  • Version 3: Beta version for testing future changes.

This practice is common in API versioning in ASP.NET Core, especially for public APIs that need backward compatibility.

📌 Summary

By implementing versioning in your ASP.NET Core Web API, you ensure:

  • Your APIs are future-proof

  • You won’t break existing client integrations

  • Developers can clearly track changes across versions

This tutorial is a great reference if you're looking to understand API versioning C# .NET Core style, or need guidance on API versioning .NET Core in general.


❓ Frequently Asked Questions (FAQ)

  1. Why should I implement API versioning in my .NET Core Web API project?

    Implementing API versioning in .NET Core is essential for long-term maintenance. It helps you introduce new features or restructure endpoints without disrupting users relying on older versions. This is considered one of the best practices in ASP.NET Core API development.

  2. Which NuGet packages are used for ASP.NET Core API versioning?

    To implement dotnet core API versioning, the two most commonly used packages are:

    • Microsoft.AspNetCore.Mvc.Versioning

    • Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer

These libraries simplify versioning setup and integration with tools like Swagger for API documentation.

  1. What are the common methods for specifying the API version in .NET Core?

    You can define the API version in ASP.NET Core using several approaches:

    • URL path versioning: /api/v1/controller

    • Query string versioning: /api/controller?api-version=1.0

    • Header-based versioning: x-api-version: 2.0

    • Media type versioning: Content-Type: application/json;ver=3.0

You can also combine these strategies using ApiVersionReader to make your ASP.NET Core Web API more flexible.

  1. How does Swagger support API versioning in ASP.NET Core?

    Swagger, when configured with AspNet API versioning, displays all available versions of your API with their routes and descriptions. It's especially useful in ASP.NET Core API tutorials to help visualize how versioning affects endpoints. Swagger integration is supported via AddVersionedApiExplorer.

  2. Is versioning supported out of the box in .NET Core Web API projects?

    No, versioning is not enabled by default. However, using Microsoft.AspNetCore.Mvc.Versioning, you can quickly enable and configure versioning in .NET Core APIs with just a few lines of code in Program.cs.

  3. Can I use namespace-based versioning in ASP.NET Core?

    Yes! Namespace-based versioning is a supported convention in Microsoft.AspNetCore.Mvc.Versioning, allowing you to group controllers by version using namespaces, which helps keep your project organized—especially in large-scale .NET Core API applications.

  4. What are the best practices for API versioning in .NET Core?

    Some API versioning best practices in .NET Core include:

    • Always specify a default version.

    • Use AssumeDefaultVersionWhenUnspecified to maintain stability.

    • Support multiple versioning methods (URL, query, header).

    • Document each version with Swagger.

    • Group controllers into versioned folders or namespaces.

These practices ensure that your ASP.NET Core Web API remains scalable and maintainable over time.

0
Subscribe to my newsletter

Read articles from Coding Droplets directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Coding Droplets
Coding Droplets