API Versioning in ASP.NET Core 8 Web API
Problem Statement
When migrating ASP.NET Core Web API projects from .NET 6/7 to .NET 8, the API versioning implementation breaks due to deprecated packages. Developers using the Microsoft.AspNetCore.Mvc.ApiExplorer package encounter compatibility issues, as this package is now deprecated in .NET 8. Attempting to replace it with Asp.Versioning.Mvc.ApiExplorer causes errors since the AddVersionedApiExplorer
extension method is unavailable. This results in a runtime exception:
Unable to resolve service for type 'Asp.Versioning.ApiExplorer.IApiVersionDescriptionProvider'...
The solution requires updated package references and a revised service configuration approach compatible with .NET 8.
Solution
1. Install Required NuGet Packages
Install both versioning packages via NuGet Package Manager or CLI:
dotnet add package Asp.Versioning
dotnet add package Asp.Versioning.Mvc.ApiExplorer
2. Configure API Versioning Services
Update the service configuration in Program.cs
by chaining AddApiExplorer()
to AddApiVersioning()
:
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
})
.AddApiExplorer(options => // Chain to AddApiVersioning
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
3. Update Swagger Configuration
Modify your Swagger setup to use the new package's IApiVersionDescriptionProvider
:
builder.Services.AddSwaggerGen();
// Register configuration for Swagger versions
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
Ensure your ConfigureSwaggerOptions
class remains unchanged from your .NET 7 implementation:
using Asp.Versioning.ApiExplorer;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
public class ConfigureSwaggerOptions : IConfigureNamedOptions<SwaggerGenOptions>
{
private readonly IApiVersionDescriptionProvider _provider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider)
{
_provider = provider;
}
public void Configure(SwaggerGenOptions options)
{
foreach (var description in _provider.ApiVersionDescriptions)
{
options.SwaggerDoc(
description.GroupName,
CreateVersionInfo(description));
}
}
private static OpenApiInfo CreateVersionInfo(ApiVersionDescription description)
{
var info = new OpenApiInfo()
{
Title = "Your API",
Version = description.ApiVersion.ToString(),
Description = "API Description"
};
if (description.IsDeprecated)
info.Description += " - DEPRECATED";
return info;
}
public void Configure(string name, SwaggerGenOptions options) => Configure(options);
}
Complete Program.cs
Example
using Asp.Versioning.ApiExplorer;
var builder = WebApplication.CreateBuilder(args);
// Add versioning and Swagger
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
})
.AddApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
var provider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerEndpoint(
$"/swagger/{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
app.Run();
Explanation
Why .NET 8 Changes Matter
The Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer package was deprecated in .NET 8. The new Asp.Versioning.Mvc.ApiExplorer package:
- Uses a modified service registration pattern
- Requires chaining
AddApiExplorer()
toAddApiVersioning()
- Returns
IApiVersioningBuilder
for fluent configuration
Key Differences from Older Versions
.NET 6/7 | .NET 8 |
---|---|
AddVersionedApiExplorer | Use AddApiExplorer() extension |
Separate service calls | Chained configuration |
Deprecated packages | Asp.Versioning namespace |
Resolving the Service Error
The original IApiVersionDescriptionProvider
error occurs because:
- The new package uses the Asp.Versioning.ApiExplorer namespace
- Service registration requires chained configuration
- The dependency injection container never receives the service without
AddApiExplorer()
The AddApiExplorer extension registers the required IApiVersionDescriptionProvider
service in the DI container, enabling injection into ConfigureSwaggerOptions
.
Swagger UI Considerations
When configuring Swagger UI (Step 3 in Program.cs
), note:
- You must resolve
IApiVersionDescriptionProvider
from the service container - Group names follow the pattern defined in
GroupNameFormat
('v'VVV
→ v1.0, v2.1, etc.) - Deprecation status appears automatically when using
description.IsDeprecated
Maintenance Tip
Consistent versioning is crucial for API stability. Test all endpoints with tools like Swagger UI or Postman after version changes.
Deprecation Handling
Use [ApiVersion("1.0", Deprecated = true)]
to mark deprecated API versions. This automatically triggers the "deprecated" flag in Swagger documentation.