### Minimal API Versioning Setup Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/how-to/version-by-header.html Example of defining a versioned endpoint using the Minimal API approach. ```csharp __ var hello = app.NewVersionedApi(); hello.MapGet( "/helloworld", () => "Hello world!" ).HasApiVersion( 1.0 ); ``` -------------------------------- ### Minimal API with versioning using NewVersionedApi Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/how-to/overview.html Example from the overview showing API versioning in a Minimal API. It configures problem details and API versioning services, creates a versioned API group with an optional logical name, and maps a GET endpoint versioned at 1.0. ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddProblemDetails(); builder.Services.AddApiVersioning(); var app = builder.Build(); var people = app.NewVersionedApi( "People" ); // ← provides optional, logical name people.MapGet( "/people", () => new[] { new Person() } ).HasApiVersion( 1.0 ); app.Run(); ``` -------------------------------- ### Run the application Source: https://dotnet.github.io/aspnet-api-versioning/getting-started.html Command to start the configured ASP.NET application. ```bash dotnet run ``` -------------------------------- ### Install Asp.Versioning.Http package Source: https://dotnet.github.io/aspnet-api-versioning/getting-started.html Use the dotnet CLI to add the required library to your project. ```bash dotnet add package Asp.Versioning.Http ``` -------------------------------- ### Interval notation examples for asp.api.version Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/grpc/versioned-fields.html Shows how to express API version ranges using interval notation. The first example indicates a field visible from 2026-07-01 up to but not including 2027-01-01. The second shows a split range that includes all versions except 2.0. ```text [2026-07-01,2027-01-01) → 2026-07-01 ≤ x < 2027-01-01 ``` ```text [(asp.api.version) = "[,2.0)", (asp.api.version) = "(2.0,]"] ``` -------------------------------- ### ApiVersion Formatting Examples Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/version-format.html Demonstrates how to use the ApiVersion class with custom format specifiers to display version information. ```csharp __ var apiVersion = new ApiVersion( 1, 0 ); Console.WriteLine( "Welcome to version " + apiVersion.ToString( "V" ) ); apiVersion = new ApiVersion( 1, 1, "Beta" ); var message = string.Format( "Welcome to version {0:VV}{0:' ('S')'}", apiVersion ); Console.WriteLine( message ); apiVersion = new ApiVersion( 2, 0 ); message = string.Format( "Welcome to version {0:VV}{0:' ('S')'}", apiVersion ); Console.WriteLine( message ); // Output: Welcome to version 1 // Output: Welcome to version 1.1 (Beta) // Output: Welcome to version 2.0 __ ``` -------------------------------- ### ApiVersion Formatting Examples Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/version-format.html Demonstrates how to use the ApiVersion class with IFormattable to format version strings. ```csharp __ var apiVersion = new ApiVersion( 1, 0 ); Console.WriteLine( "Welcome to version " + apiVersion.ToString( "V" ) ); apiVersion = new ApiVersion( 1, 1, "Beta" ); var message = string.Format( "Welcome to version {0:VV}{0:' ('S')'}", apiVersion ); Console.WriteLine( message ); apiVersion = new ApiVersion( 2, 0 ); message = string.Format( "Welcome to version {0:VV}{0:' ('S')'}", apiVersion ); Console.WriteLine( message ); // Output: Welcome to version 1 // Output: Welcome to version 1.1 (Beta) // Output: Welcome to version 2.0 ``` -------------------------------- ### Implement OPTIONS method with Minimal APIs Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/version-discovery.html Example of mapping the OPTIONS method to a route in a Minimal API to support version discovery. ```csharp using static Microsoft.AspNetCore.Http.HttpMethods; // OPTIONS ~/api/myservice?api-version=[1.0|2.0|3.0] app.MapMethods("/api/myservice", [Options], ( HttpContext context ) => { context.Response.Headers.Allow = new( [Get, Post, Options] ); return Results.Ok(); }); ``` ```http HTTP/2 200 allow: GET, POST, OPTIONS api-supported-versions: 1.0, 2.0, 3.0 ``` -------------------------------- ### Simplified API Versioning Configuration Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0011.html This example shows the recommended approach of removing the redundant assignment to rely on the default configuration. ```csharp builder.Services.AddApiVersioning(); ``` -------------------------------- ### Example HTTP Request with Multiple Media Types Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/how-to/version-by-media-type.html An example of an HTTP request where multiple media types are provided in the Accept header, potentially causing ambiguity in version matching. ```http GET api/helloworld HTTP/2 host: localhost accept: application/json;v=1.0;q=0.8,application/signed-exchange;v=b3;q=0.9 ``` -------------------------------- ### Corrected API Version Literal Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0001.html This example shows the corrected implementation using a well-formed API version string '1.0'. ```csharp [ApiController] [ApiVersion("1.0")] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Corrected API Version Status Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0003.html This example shows the corrected API version status 'preview.1' which adheres to the required naming conventions. ```csharp [ApiController] [ApiVersion(2.0, "preview.1")] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Implement OPTIONS method with Controllers Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/version-discovery.html Example of implementing the OPTIONS method within a controller action to support version discovery. ```csharp using static Microsoft.AspNetCore.Http.HttpMethods; // OPTIONS ~/api/myservice?api-version=[1.0|2.0|3.0] [HttpOptions] public IActionResult Options() { Response.Headers.Allow = new( [Get, Post, Options] ); return Ok(); } ``` ```http HTTP/2 200 allow: GET, POST, OPTIONS api-supported-versions: 1.0, 2.0, 3.0 ``` -------------------------------- ### ControllerNameAttribute example Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/how-to/naming-conventions.html Shows how to explicitly set a controller name using the ControllerNameAttribute, which is useful when the controller name must match an OData entity set name. This example uses HelloWorld2Controller but names it HelloWorld. ```csharp [ApiVersion( 2.0 )] [RoutePrefix( "helloworld" )] [ControllerName( "HelloWorld" )] public class HelloWorld2Controller : ControllerBase { [Route] public string Get() => "Hello world v2.0!"; } ``` -------------------------------- ### Test versioned endpoints with curl Source: https://dotnet.github.io/aspnet-api-versioning/getting-started.html Example curl commands to verify the versioned endpoints. ```bash curl https://localhost:5001/helloworld?api-version=1.0 ``` ```bash curl https://localhost:5001/helloworld?api-version21.0 ``` -------------------------------- ### Configure deprecation and sunset policies with AddApiVersioning Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/version-policies.html C# configuration example using AddApiVersioning to define deprecation and sunset policies with effective dates and links. ```csharp AddApiVersioning( options => { // version 1.0 deprecates 1/1/2022 with a public policy page options.Policies.Deprecate( 1.0 ) .Effective( 2022, 1, 1 ) .Link( "https://docs.api.com/policies/deprecation.html" ) .Title( "Version Deprecation Policy" ) .Type( "text/html" ); // version 1.0 sunsets 4/1/2022 with a public policy page options.Policies.Sunset( 1.0 ) .Effective( 2022, 4, 1 ) .Link( "https://docs.api.com/policies/sunset.html" ) .Title( "Version Sunset Policy" ) .Type( "text/html" ); // public policy page for version 2.0 without a sunset date options.Policies.Sunset( 2.0 ) .Link( "https://docs.api.com/policies/sunset.html" ) .Title( "Version Sunset Policy" ) .Type( "text/html" ); }) ``` -------------------------------- ### Correct OData route component configuration Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0023.html This example demonstrates adding route components through the versioned AddOData options, ensuring they are applied per API version. ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddControllers().AddOData(); builder.Services.AddApiVersioning().AddOData( options => options.AddRouteComponents( "api" ) ); ``` -------------------------------- ### HTTP Request and Response with Custom Header Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/how-to/version-by-header.html Example of a client request using the x-ms-version header and the corresponding server response. ```http __ GET api/helloworld HTTP/2 host: localhost x-ms-version: 1.0 ``` ```http __ HTTP/2 200 host: localhost content-type: text/plain content-length: 12 Hello world! ``` -------------------------------- ### Define Versioned Controllers Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/how-to/version-by-media-type.html Example controllers for version 1.0 and 2.0 using ApiVersion and RoutePrefix attributes. ```csharp namespace Services.V1 { [ApiVersion( 1.0 )] [RoutePrefix( "api/helloworld" )] public class HelloWorldController : ApiController { [Route] public string Get() => "Hello world!"; } } namespace Services.V2 { [ApiVersion( 2.0 )] [RoutePrefix( "api/helloworld" )] public class HelloWorldController : ApiController { [Route] public string Get() => "Hello world!"; [Route] public string Post( string text ) => text; } } ``` -------------------------------- ### WebApplication builder without description Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0025.html Shows the minimal setup that triggers AV0025: the OpenAPI document is generated without a description because the project does not provide one. ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddApiVersioning().AddApiExplorer().AddOpenApi(); ``` -------------------------------- ### OData endpoint with API versioning Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/quick-starts/new-services.html Shows an OData controller with [ApiVersion(1.0)] and the corresponding Program.cs setup using AddApiVersioning().AddOData() with model configuration. ```csharp [ApiVersion( 1.0 )] public class PeopleController : ODataController { [EnableQuery] public IActionResult Get() => Ok( new[] { new Person() } ); } ``` ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddControllers().AddOData(); builder.Services.AddProblemDetails(); builder.Services.AddApiVersioning().AddOData( options => { options.ModelBuilder.DefaultModelConfiguration = ( builder, apiVersion, routePrefix ) => { builder.EntitySet( "People" ); }; options.AddRouteComponents(); } ); var app = builder.Build(); app.MapControllers(); app.Run(); ``` -------------------------------- ### Corrected API Explorer Configuration Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0024.html This example demonstrates the fix by removing the redundant assignment in AddApiExplorer, allowing it to inherit the value from the API versioning options. ```csharp builder.Services.AddApiVersioning( options => { options.DefaultApiVersion = new ApiVersion( 2.0 ); } ) .AddApiExplorer(); ``` -------------------------------- ### Corrected API Version Date Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0008.html This example shows the corrected API version using a valid date. ```csharp [ApiController] [ApiVersion(2026, 2, 28)] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Corrected API version format example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0009.html This example shows the corrected format specifier to avoid runtime errors. ```csharp Console.WriteLine(new ApiVersion(2026, 1, 1).ToString("'v'VV")); ``` -------------------------------- ### Invalid API version format example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0009.html This example demonstrates an invalid format specifier that causes a runtime exception. ```csharp Console.WriteLine(new ApiVersion(2026, 1, 1).ToString("'unterminated")); ``` -------------------------------- ### Configure versioned Hello World service Source: https://dotnet.github.io/aspnet-api-versioning/getting-started.html Sets up a WebApplication with two versions of a /helloworld endpoint using MapGroup and HasApiVersion. ```csharp using Asp.Versioning; var builder = WebApplication.CreateBuilder(args); builder.Services.AddProblemDetails(); builder.Services.AddApiVersioning(); var app = builder.Build(); var helloworld = app.NewVersionedApi().MapGroup("/helloworld"); var v1 = helloworld.MapGroup("/").HasApiVersion(1.0); var v2 = helloworld.MapGroup("/").HasApiVersion(2.0); // GET /helloworld?api-version=1.0 v1.MapGet("/", (ApiVersion version) => $"Hello World! (v{version})"); // GET /helloworld?api-version=2.0 v2.MapGet("/", (ApiVersion version) => $"Hello World! (v{version})"); app.Run(); ``` -------------------------------- ### Invalid API Version Month Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0006.html This example demonstrates an invalid API version where the month is set to 13, which will cause a runtime error. ```csharp [ApiController] [ApiVersion(2026, 13, 1)] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Invalid API Version Date Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0008.html This example demonstrates an invalid API version using February 29, 2026, which is not a leap year. ```csharp [ApiController] [ApiVersion(2026, 2, 29)] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Invalid API Version Day Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0007.html This example demonstrates an invalid API version where the day is set to 32, which will cause a runtime exception. ```csharp [ApiController] [ApiVersion(2026, 1, 32)] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### HTTP request and response using x-ms-version header Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/how-to/version-by-header.html Example HTTP request using the x-ms-version header to request version 1.0, followed by the corresponding HTTP response with status 200 and the body 'Hello world!'. ```http GET api/helloworld HTTP/2 host: localhost x-ms-version: 1.0 ``` ```http HTTP/2 200 host: localhost content-type: text/plain content-length: 12 Hello world! ``` -------------------------------- ### Invalid API Version Literal Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0001.html This example demonstrates an invalid API version string 'abc' applied to a controller, which will trigger a runtime error. ```csharp [ApiController] [ApiVersion("abc")] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Controller implementations for protocol transition Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/odata/protocol-transition.html Example showing three versions of an Orders controller, where version 2.0 uses OData while versions 1.0 and 3.0 use standard REST semantics. ```csharp [ApiVersion( 1.0 )] public class OrdersController : ApiController { public IHttpActionResult Get() => Ok(); } [ApiVersion( 2.0 )] [ControllerName( "Orders" )] [ODataRoutePrefix( "Orders" )] public class Orders2Controller : ODataController { [ODataRoute] public IHttpActionResult Get() => Ok(); } [ApiVersion( 3.0 )] [ControllerName( "Orders" )] public class Orders3Controller : ApiController { public IHttpActionResult Get() => Ok(); } ``` -------------------------------- ### Corrected API Version Year Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0005.html This example shows the corrected API version using a valid year within the 1 to 9999 range. ```csharp [ApiController] [ApiVersion(2026, 1, 1)] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Invalid API Version Status Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0003.html This example demonstrates an invalid API version status 'preview-1' which contains a hyphen, causing a runtime error. ```csharp [ApiController] [ApiVersion(2.0, "preview-1")] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Invalid API Version Year Example Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0005.html This example demonstrates an invalid API version where the year 10,000 is specified, which exceeds the allowed range of 1 to 9999. ```csharp [ApiController] [ApiVersion(10_000, 1, 1)] [Route("[controller]")] public class ExampleController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Initial HelloWorldController implementation Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/how-to/version-by-query-string.html The initial version of a controller without API version attribution, which defaults to version 1.0. ```csharp [RoutePrefix( "api/helloworld" )] public class HelloWorldController : ApiController { [Route] public string Get() => "Hello world!"; } ``` -------------------------------- ### Register and map gRPC service with API versioning Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/grpc/overview.html Configures the application to add API versioning and gRPC services, then maps the GreeterService with API version 1.0. This setup allows the gRPC service to be versioned and disambiguated by the requested API version. ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddApiVersioning().AddGrpc(); var app = builder.Build(); var greeter = app.NewVersionedApi(); greeter.MapGrpcService().HasApiVersion( 1.0 ); app.Run(); ``` -------------------------------- ### Define gRPC service with API versioning in proto file Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/grpc/overview.html Defines a gRPC service 'Greeter' with a SayHello RPC that includes an HTTP GET annotation for '/greet/{name}?api-version=1.0'. This proto file is used to generate the service stubs for gRPC with API versioning. ```protobuf syntax = "proto3"; import "google/api/annotations.proto"; package greet; message HelloRequest { string name = 1; } message HelloReply { string message = 1; } service Greeter { // GET /greet/{name}?api-version=1.0 rpc SayHello (HelloRequest) returns (HelloReply) { option (google.api.http) = { get: "/greet/{name}" response_body: "message" }; } } ``` -------------------------------- ### Controller-based API Versioning Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/how-to/version-by-header.html Example of defining versioned controllers using the ApiVersion attribute. ```csharp __ namespace Services.V1 { [ApiVersion( 1.0 )] [ApiController] [Route( "api/[controller]" )] public class HelloWorldController : ControllerBase { [HttpGet] public string Get() => "Hello world!"; } } namespace Services.V2 { [ApiVersion( 2.0 )] [ApiController] [Route( "api/[controller]" )] public class HelloWorldController : ControllerBase { [HttpGet] public string Get() => "Hello world!"; [HttpPost] public string Post( string text ) => text; } } ``` -------------------------------- ### Controller: Implement multiple versions in one controller Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/how-to/version-interleaving.html Use this controller-based approach to implement multiple API versions in a single controller class. The HelloWorld2Controller handles versions 2.0 and 3.0, with the GetV3 action mapped to version 3.0. ```csharp [ApiVersion( 1.0 )] [ApiController] [Route( "api/[controller]" )] public class HelloWorldController : ControllerBase { [HttpGet] public string Get() => "Hello world v1.0!"; } [ApiVersion( 2.0 )] [ApiVersion( 3.0 )] [ApiController] [Route( "api/helloworld" )] public class HelloWorld2Controller : ControllerBase { [HttpGet] public string Get() => "Hello world v2.0!"; [HttpGet, MapToApiVersion( 3.0 )] public string GetV3() => "Hello world v3.0!"; } ``` -------------------------------- ### Configure API Versioning and Swashbuckle in Program.cs Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/docs/swashbuckle.html The complete setup for registering API versioning services and configuring the Swagger UI to display endpoints for all API versions. ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddControllers(); builder.Services.AddApiVersioning().AddMvc().AddApiExplorer(); builder.Services.AddTransient, ConfigureSwaggerOptions>(); builder.Services.AddSwaggerGen( options => options.OperationFilter() ); var app = builder.Build(); app.UseSwagger(); app.UseSwaggerUI( options => { foreach ( var description in app.DescribeApiVersions() ) { options.SwaggerEndpoint( $"/swagger/{description.GroupName}/swagger.json", description.GroupName ); } } ); app.MapControllers(); app.Run(); ``` -------------------------------- ### Default ApiVersionReader with URL segment routes Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0015.html Shows the default setup where no explicit reader is configured. Every route carries the apiVersion constraint, so the version is only read from the URL segment, while the query string is searched on every request and never finds a value. ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddApiVersioning(); var app = builder.Build(); app.MapGet( "/v{version:apiVersion}/order", () => Results.Ok() ).HasApiVersion( 1.0 ); app.MapGet( "/v{version:apiVersion}/customer", () => Results.Ok() ).HasApiVersion( 1.0 ); app.Run(); ``` -------------------------------- ### Configure OData API versioning in Startup Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/odata/overview.html Shows the Startup class configuration for OData API versioning. It adds API versioning, builds a VersionedODataModelBuilder with a PersonModelConfiguration, and maps the versioned OData route 'odata' to 'api'. ```csharp public class Startup { public void Configuration( IAppBuilder appBuilder ) { var configuration = new HttpConfiguration(); var httpServer = new HttpServer( configuration ); configuration.AddApiVersioning(); var modelBuilder = new VersionedODataModelBuilder( configuration ) { ModelConfigurations = { new PersonModelConfiguration() } }; configuration.MapVersionedODataRoute( "odata", "api", modelBuilder ); appBuilder.UseWebApi( httpServer ); } } ``` -------------------------------- ### Controller versioning conflict Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0019.html Example of a controller marked as version-neutral while an action within it attempts to claim a specific version. ```csharp [ApiController] [ApiVersionNeutral] [Route( "[controller]" )] public class ExampleController : ControllerBase { [HttpGet] [ApiVersion( 2.0 )] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Initial PeopleController implementation Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/how-to/version-by-query-string.html An initial OData controller implementation without explicit API versioning. ```csharp [ODataRoutePrefix( "People" )] public class PeopleController : ODataController { [ODataRoute] public IHttpActionResult Get( ODataQueryOptions options ) => Ok( new[]{ new Person() } ); } ``` -------------------------------- ### Define an API Controller with GroupName Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/docs/options.html An example of a controller using the ApiExplorerSettings attribute to explicitly set a group name. ```csharp [ApiVersion( 1.0 )] [ApiExplorerSettings( GroupName = "Sales" )] [Route( "[controller]" )] public class OrderController : ControllerBase { [HttpGet] public IActionResult Get() => Ok(); } ``` -------------------------------- ### Enable API versioning in Startup.cs Source: https://dotnet.github.io/aspnet-api-versioning/aspnet-core/config/overview.html Use this configuration in the ConfigureServices method of the Startup.cs file for ASP.NET Core applications. It adds controllers, problem details, and API versioning with MVC support. The AddMvc() call is unnecessary for Minimal APIs. ```csharp public void ConfigureServices( IServiceCollection services ) { services.AddControllers(); services.AddProblemDetails(); services.AddApiVersioning() .AddMvc(); // ← brings in MVC Core; unnecessary for Minimal APIs // remaining setup omitted for brevity } ``` -------------------------------- ### Corrected OpenAPI service registration Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0029.html This example shows the corrected pattern where the redundant call to AddOpenApi() on the service collection is removed. ```csharp var builder = WebApplication.CreateBuilder( args ); builder.Services.AddApiVersioning().AddOpenApi(); ``` -------------------------------- ### Implement IODataQueryOptionDescriptionProvider Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/docs/odata-options.html Define a custom provider to override default OData query option descriptions. ```csharp public interface IODataQueryOptionDescriptionProvider { string Describe( AllowedQueryOptions queryOption, ODataQueryOptionDescriptionContext context ); } ``` -------------------------------- ### Redundant API Explorer Configuration Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0024.html This example shows an explicit assignment of DefaultApiVersion in both AddApiVersioning and AddApiExplorer, which triggers the AV0024 diagnostic. ```csharp builder.Services.AddApiVersioning( options => { options.DefaultApiVersion = new ApiVersion( 2.0 ); } ) .AddApiExplorer( options => { options.DefaultApiVersion = new ApiVersion( 2.0 ); } ); ``` -------------------------------- ### Sample folder layout with numeric API versions Source: https://dotnet.github.io/aspnet-api-versioning/aspnet/config/conventions.html Sample folder layout showing numeric API versions (v1, v2, v2_5) under the Contoso.Api namespace. This layout is used with the VersionByNamespaceConvention. ```text Contoso └ Api ├─ v1 │ └ Controllers ├─ v2 │ └ Controllers └─ v2_5 └ Controllers ``` -------------------------------- ### Redundant Default API Version Assignment Source: https://dotnet.github.io/aspnet-api-versioning/diagnostic/av0011.html This example shows an explicit assignment of ApiVersion.Default, which is redundant because 1.0 is the default value. ```csharp builder.Services.AddApiVersioning( options => { options.DefaultApiVersion = ApiVersion.Default; } ); ```