This release includes some big new features but is fully backward compatible with 10.0.0. The new features include versioned model member filtering, Roslyn analyzers, gRPC preview support, and a number of servicing patches since the previous release.
Fixes
All Platforms
- Parsing an API version whose status ends in
'.'no longer succeeds silently - Very large padding values in a format string no longer cause a stack overflow
- Incorrect lower and upper bounds when matching API version ranges
- Parsing a positive integer no longer allows whitespace or a leading
'-'
ASP.NET Core
- Routes are no longer incorrectly evicted from the route table (#1138)
- Fixed routing of unversioned endpoints
- Fixed extracting an API version that includes a status when versioning by URL segment (#1187)
- A user-registered
IProblemDetailsWriteris preserved byAddApiVersioning()(#1191)
ASP.NET Core OpenAPI
- Support for more XML comment tags (#1205)
- Fixed the error message reported for an unmapped JSON property
- Fixed descriptions applied to filtered members
Features
All Platforms
- New
ApiVersionRangetype for matching a set of API versions using the same interval notation as a package version1.0→x ≥ 1.0[1.0]→x == 1.0(1.0,)→x > 1.0(,1.0]→x ≤ 1.0[1.0,2.0)→1.0 ≤ x < 2.0- Multiple rules are combined as a logical or;
ApiVersionRange.AnyandApiVersionRange.Emptyare provided for
the degenerate cases - A range matches API versions; it does not define them. API versions must still be explicitly declared
- New
VisibleInApiVersionAttributeindicates the range of API versions a data member is visible in; for example,
[VisibleInApiVersion("2.0")] - New
IAnnotation<TKey, TValue>abstraction for associating out-of-band metadata with a member [StringSyntax]is now applied to API version inputs so the IDE and analyzers understand them; the recognized
syntaxes areApiVersion,ApiVersionRange, andApiVersionFormat
Analyzers
API Versioning now ships Roslyn analyzers. There is no new package to install — the core rules are packed into Asp.Versioning.Abstractions and the API rules are packed into Asp.Versioning.Http, so any application that already references API Versioning picks them up transitively.
There is an initial set of 31 rules. You can find all of the rule information in the new diagnostics wiki topic.
Notes:
- Every rule has a
helpLinkUrithat resolves to its documentation page - Individual rules can be configured through
.editorconfigas usual - All analyzers can be turned off with a single MSBuild property:
<PropertyGroup> <EnableApiVersioningAnalyzers>false</EnableApiVersioningAnalyzers> </PropertyGroup>
ExcludeAssets="analyzers"on aPackageReferencewill not work because the package is also reached through
the dependencies of other packages and NuGet combines the assets from every path
ASP.NET Web API (Classic) is not currently supported. If there is demand, I will consider the support, but I presume
little new development is happening on the older platform.
ASP.NET Core
Data members can now be versioned independently of the endpoint that returns them. Annotate a property with [VisibleInApiVersion] and the member is omitted from responses for API versions outside the range:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
[VisibleInApiVersion( "2.0" )]
public Address? HomeAddress { get; set; }
[VisibleInApiVersion( "[1.0,2.0)" )]
public string? LegacyEmail { get; set; }
}- Works for both Minimal APIs and MVC (Core)
- Filtering members is currently only support for the JSON media type
- Filtering applies on the way in as well as the way out, which closes the corresponding over-posting gap
AddApiVersioning()now registersIHttpContextAccessorso the requested API version is available during
serialization[VisibleInApiVersion]is part of the core abstractions and can be used in your model libraries without any
dependency on ASP.NET
ASP.NET Core API Explorer
- The API explorer describes only the model members visible in the API version being explored via the new
VersionedModelMetadata,VersionedModelMetadataProvider, andDelegatingModelMetadatatypes - Only models that are actually explored are filtered for visibility
ASP.NET Core OpenAPI
- Generated schemas reflect per-version member visibility, so the documented shape of a model matches what the API
actually returns for that version - Significantly expanded XML comment support:
<remarks>now takes precedence over<description><b>and<i>are converted to and retained as Markdown<a href="..."/>is converted to and retained as a hyperlink<paramref name="..."/>is rendered as inline code<list>,<item>,<term>,<description>,<value>, and<example>are supported<inheritdoc/>is resolved for summaries- Multi-line code fences from
<code>blocks are properly closed
ASP.NET Core with gRPC (Preview)
Two new packages add API Versioning to gRPC services: Asp.Versioning.Grpc and Asp.Versioning.Grpc.ApiExplorer. This is a new set of features that will run in preview to give gRPC service authors a chance to try things out and report any issues or gaps.
The following is a basic example showing all of the parts coming together.
services.AddApiVersioning()
.AddGrpc()
.AddGrpcApiExplorer()
.AddOpenApi();
var people = app.NewVersionedApi( "People" );
people.MapGrpcService<PeopleService>()
.HasApiVersion( 1.0 )
.HasApiVersion( 2.0 )
.HasApiVersion( 3.0 );- Services are versioned with the same conventions used everywhere else — a single implementation can support several
API versions, or implementations can be split across versions - Message fields are annotated with the API versions they belong to using the new
asp/api/annotations.proto:import "asp/api/annotations.proto"; message Person { int32 id = 1; string first_name = 2; string last_name = 3; Address home_address = 4 [(asp.api.version) = "2.0"]; string phone = 5 [(asp.api.version) = "3.0"]; }
- The option is
repeated, so a field split across disjoint ranges repeats the option - A field with no annotation is included in every API version
- The option is
- A server interceptor filters fields out of requests and responses — including streaming in both directions — so a
client on1.0can neither see nor post a field that was introduced in3.0 - JSON transcoded gRPC services are described by the API explorer and appear in the OpenAPI document with the API
version route segment and well-known protobuf types mapped to their correct schemas
The gRPC OpenAPI Example demonstrates an end-to-end working solution.
Breaking Changes
All Platforms
- The analyzers are on by default. They ship inside
Asp.Versioning.AbstractionsandAsp.Versioning.Http, which
means upgrading turns them on for every project that references API versioning — directly or transitively. AV0012,
AV0018, and AV0019 default to error severity, so an existing application that trips one of them will fail to build
until the underlying problem is fixed, the rule is downgraded in.editorconfig, or
<EnableApiVersioningAnalyzers>false</EnableApiVersioningAnalyzers>is set. Before these rules existed, an
application should have either encountered runtime exceptions or not functioned as expected. These rules are catching
mistakes early rather than imposing specific dogma about how your application must be defined.
ASP.NET Core
AddApiVersioning()now callsAddHttpContextAccessor(). This is additive and should be transparent, but it does mean
IHttpContextAccessoris registered in applications that previously did not have it
Documentation
The wiki has served the community well for many years, but it had gotten tired and it was due for some much needed love and updates. I've reworked the wiki into a new GitHub Pages site using mdBook.
- The wiki has been ported to GitHub Pages and is now published at dotnet.github.io/aspnet-api-versioning with search, per-page tables of contents, and side-by-side content for each supported flavor of ASP.NET
- README badges and links throughout the repository now point at the new site
- The old wiki pages still exist so that old links are not broken
- All future links should link to the new content
Why change?
- There was little-to-no control over wiki page names, which makes it difficult for SEO
- The wiki HTML support is much more limited that GitHub Pages
- Theming is also supported
- The wiki was considerable in size, but you couldn't search it; now you can
- The project started with ASP.NET Web API (Classic) a decade ago, but ASP.NET Core is now the de facto platform
- ASP.NET Core and Web API (Classic) have been split apart
- There will be overlap in search, but everything else is cleanly separated
- Errors and updates. There has never been a good way for the community to create pull requests to update content
- The content lifecycle was outside of the repository content; now it's side-by-side
- This helps keep the content current and fresh
- Printing now has first-class support
It certainly possible that some links or content are incorrect after the migration. Please report any errors or submit a pull request
and they will be fixed promptly.
Release Notes
- Package release notes are now emitted through the
PackageReleaseNotesproperty instead of being appended to the
package README (#1211) - Asp.Versioning.OData and Asp.Versioning.OpenAPI are no longer
rc; both were promoted to stable during servicing and ship as10.2.0 - Asp.Versioning.Grpc and Asp.Versioning.Grpc.ApiExplorer are new in this release and ship at
10.2.0-preview.1alongside everything else Microsoft.OpenApiwas updated to2.7.5due to a vulnerability and pinned to below3.0.0after a major version
incompatibility
Feedback
Thanks to everyone who contributed to this release, whether through code, issues, or test driving the changes.