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

## 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**](http://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.

%[https://www.youtube.com/watch?v=yw5NS-FNvew] 

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Full source code</strong> is available on our <a target="_self" rel="noopener noreferrer nofollow" href="https://www.patreon.com/posts/125744916" style="pointer-events: none">Patreon</a>. Get access and follow along!</div>
</div>

## 🚀 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**](http://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:

```csharp
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:
    

```csharp
[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:

```csharp
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.

```csharp
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:

```csharp
[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`:

```csharp
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:
    
    ```csharp
     x-api-version: 2.0
    ```
    
3. **Media Type Versioning**  
    Embed the version in the `Content-Type` or `Accept` header:
    
    ```csharp
     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**](http://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**](http://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**](http://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](https://www.patreon.com/posts/125744916).

## 🧑‍💻 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.
    
3. ### 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.
    
4. ### How does Swagger support API versioning in [ASP.NET](http://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`.
    
5. ### 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`.
    
6. ### Can I use namespace-based versioning in [ASP.NET](http://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.
    
7. ### 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.
