Skip to content

Bits of .NET

Daily micro-tips for C#, SQL, performance, and scalable backend engineering.

  • Asp.Net Core
  • C#
  • SQL
  • JavaScript
  • CSS
  • About
  • ErcanOPAK.com
  • No Access
  • Privacy Policy
Asp.Net Core

.NET Core: Implement API Versioning Without Breaking Clients

- 30.05.26 - ErcanOPAK

🔄 V1, V2, V3 — All Running Simultaneously

Change API = break clients. API versioning lets you run multiple versions. Old clients stay on V1, new clients use V2. No downtime.

📝 Setup Versioning

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

// Program.cs
builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.ReportApiVersions = true;
    options.ApiVersionReader = ApiVersionReader.Combine(
        new QueryStringApiVersionReader("api-version"),
        new HeaderApiVersionReader("api-version"),
        new MediaTypeApiVersionReader("api-version")
    );
}).AddApiExplorer(options =>
{
    options.GroupNameFormat = "'v'VVV";
    options.SubstituteApiVersionInUrl = true;
});

🎯 Version Controllers

// V1 Controller
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/users")]
public class UsersV1Controller : ControllerBase
{
    [HttpGet]
    public IEnumerable Get() => _service.GetUsersV1();
}

// V2 Controller (new fields)
[ApiController]
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/users")]
public class UsersV2Controller : ControllerBase
{
    [HttpGet]
    public IEnumerable Get() => _service.GetUsersV2();
}

// Multiple versions same controller
[ApiController]
[ApiVersion("1.0")]
[ApiVersion("2.0")]
[Route("api/users")]
public class UsersController : ControllerBase
{
    [HttpGet, MapToApiVersion("1.0")]
    public UserV1 GetV1() { }
    
    [HttpGet, MapToApiVersion("2.0")]
    public UserV2 GetV2() { }
}

âś… Versioning Strategies

  • URL path: /api/v1/users, /api/v2/users (most common)
  • Query string: /api/users?api-version=1.0
  • Header: api-version: 1.0 (clean URLs)
  • Media type: Accept: application/json;version=1.0

đź’ˇ Deprecation

[ApiController]
[ApiVersion("1.0", Deprecated = true)]
[Route("api/v1/users")]
public class UsersV1Controller : ControllerBase
{
    // Returns warning header: API v1 is deprecated
}

// Response includes deprecation warning
// api-supported-versions: 1.0, 2.0
// api-deprecated-versions: 1.0

“Breaking change needed. Deployed V2, kept V1 running. Mobile apps on V1 worked fine. New web app used V2. No downtime, no angry clients. API versioning saves careers.”

— API Architect

Related posts:

.NET Core “Configuration Not Updating” — Missing ReloadOnChange

.NET Core: Implementing Clean Architecture for Enterprise Apps

ASP.NET Core “Slow Startup” — Reflection Scanning Trap

Post Views: 9

Post navigation

Git: Create Custom Aliases for Frequently Used Commands
SQL: Use UPSERT (INSERT ON CONFLICT) for Insert or Update

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

June 2026
M T W T F S S
1234567
891011121314
15161718192021
22232425262728
2930  
« May    

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (882)
  • Get the First and Last Word from a String or Sentence in SQL (838)
  • How to select distinct rows in a datatable in C# (808)
  • How to make theater mode the default for Youtube (805)
  • Add Constraint to SQL Table to ensure email contains @ (580)
  • How to enable, disable and check if Service Broker is enabled on a database in SQL Server (579)
  • Average of all values in a column that are not zero in SQL (538)
  • How to use Map Mode for Vertical Scroll Mode in Visual Studio (505)
  • Find numbers with more than two decimal places in SQL (454)

Recent Posts

  • C#: Use String Interpolation Instead of Concatenation
  • C#: Use Tuples to Return Multiple Values from Methods
  • SQL: Use ISNULL and NULLIF for Smart NULL Handling
  • .NET Core: Use Data Annotations for Model Validation
  • Git: Use Git Clean to Remove Untracked Files
  • Ajax: Add Custom Headers to Fetch Requests
  • JavaScript: Use console.table to Display Arrays as Tables
  • HTML: Use Spellcheck Attribute to Enable Browser Spell Check
  • CSS: Use user-select to Prevent Text Selection
  • Windows 11: Use Snipping Tool for Instant Screenshots

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (882)
  • Get the First and Last Word from a String or Sentence in SQL (838)
  • How to select distinct rows in a datatable in C# (808)
  • How to make theater mode the default for Youtube (805)

Recent Posts

  • C#: Use String Interpolation Instead of Concatenation
  • C#: Use Tuples to Return Multiple Values from Methods
  • SQL: Use ISNULL and NULLIF for Smart NULL Handling
  • .NET Core: Use Data Annotations for Model Validation
  • Git: Use Git Clean to Remove Untracked Files

Social

  • ErcanOPAK.com
  • GoodReads
  • LetterBoxD
  • Linkedin
  • The Blog
  • Twitter
© 2026 Bits of .NET | Built with Xblog Plus free WordPress theme by wpthemespace.com