Migration From Previous Versions
This topic serves as the guide for migrating from version <= 5.x.x to version >= 6.0.0. The majority of this
information has been outlined in previous discussions.
Note
If you’d like more information on the background context, you can read the Hello Project “Asp” announcement.
For the most part, you can expect the required changes to be a new package identifier and different namespaces. It is entirely possible that you may update those and find the rest of the code to be identical. The mileage will vary depending on your level of customization, but you can expect the changes to be trivial in most cases.
Package Identifiers
The original Microsoft.* packages are now deprecated and will only undergo servicing:
| Package | Version | TFM |
|---|---|---|
| Microsoft.AspNet.WebApi.Versioning | <= 5.x.x | net45 |
| Microsoft.AspNet.WebApi.Versioning.ApiExplorer | <= 5.x.x | net45 |
| Microsoft.AspNet.OData.Versioning | <= 5.x.x | net45 |
| Microsoft.AspNet.OData.Versioning.ApiExplorer | <= 5.x.x | net45 |
All new features and platform support will use the Asp.Versioning.* prefix:
| Package | Version | TFM |
|---|---|---|
| Asp.Versioning.Abstractions | 6.0.0+ | net6.0+, netstandard1.0, netstandard2.0 |
| Asp.Versioning.WebApi | 6.0.0+ | net45, net472 |
| Asp.Versioning.WebApi.ApiExplorer | 6.0.0+ | net45, net472 |
| Asp.Versioning.WebApi.OData | 6.0.0+ | net45, net472 |
| Asp.Versioning.WebApi.OData.ApiExplorer | 6.0.0+ | net45, net472 |
Namespaces
As the project is no longer part of Microsoft, all namespaces have become Asp.Versioning.*. It didn’t make sense to
keep using Microsoft.* when things don’t line up. Furthermore, what namespace should all new code live under?
Continuing to use the Microsoft namespace seemed wrong. An interesting benefit, however, is that using
Api.Versioning.* allows for more consistency across the ASP.NET Web API and Core implementations. The existing
differences in library namespaces for shared code often led to conditional compiler directives. For ease of use,
extension methods will continue to live in the namespace they correspond to.
API Version
The format and default implementation has not changed, but parsing has been broken apart. The new IApiVersionParser
service has been introduced to support this capability. ApiVersion.Parse and ApiVersion.TryParse have been removed,
but are replaced by ApiVersionParser.Default, which will provide a default implementation.
ApiVersion.GroupVersion in .NET 6.0 and beyond is now represented as DateOnly. DateOnly accurately represents how
a group or date version was always meant to be, but couldn’t be represented without introducing its own type due to the
design of DateTime. The .NET Standard and .NET Framework representations will continue to use DateTime.
API Version Reader
IApiVersionReader.Read now returns IReadOnlyList<string> instead of string?. There are a few reasons for this
change. First, the Null Mistake is removed as an empty list is completely acceptable. Second, it was entirely possible
for a particular reader implementation to return more than one value. Consider that ?api-version=1.0&api-version=2.0
would return both 1.0 and 2.0. In previous versions, the implementation would instead throw
AmbiguousApiVersionException that would have to be handled. That behavior becomes problematic for the server to
correctly report the response to the client. Reading multiple API version values in and of itself isn’t exceptional,
it’s just an invalid client request. ApiVersionReader.Combine also enables combining different types of readers
through composition. Readers for different parts of a request are even more likely to return different values.
Refactoring to return a list makes it very simple to return all of the raw API versions provided without any exceptions
and regardless of where they were read from.
API Version Reporting
IReportApiVersions.Report now accepts the entire HTTP response as opposed to just the headers. Accepting only the
headers was an over-normalization that wasn’t really necessary. Additional information was also necessary to support
sunset policies. The Report overload that accepts Lazy<ApiVersionModel> has been removed as it’s no longer used
or necessary.
API Version Model Extensions
Extension methods related to retrieving an ApiVersionModel have been supplanted by the new extension property
ApiVersionMetadata. The previous GetApiVersionModel() extension method, for example, was a shortcut for
GetApiVersionModel(ApiVersionMapping.Explicit). A new type - ApiVersionMetadata - has been introduced that unifies
the metadata implementation across ASP.NET platforms.
The following is the mapping between the old and new extension methods or properties:
GetApiVersionModel(ApiVersionMapping) → ApiVersionMetadataGetApiVersionModel() → ApiVersionMetadata.Map(ApiVersionMapping.Explicit)MappingTo(ApiVersion) → ApiVersionMetadata.MappingTo(ApiVersion)IsMappedTo(ApiVersion) → ApiVersionMetadata.IsMappedTo(ApiVersion)
Error Responses
The IErrorResponseProvider service had been the hook to provide custom error responses. Problem Details (RFC 7807)
had only just been ratified when this project started and they were not part of ASP.NET yet. ASP.NET Core eventually
added first-class support for Problem Details and IErrorResponseProvider had an adapter implementation for alignment
in previous versions. Now that Problem Details are the de factor method for error reporting, it no longer makes sense to
retain IErrorResponseProvider and it has been removed.
The error responses bodies provided by IErrorResponseProvider complied with the
Microsoft REST Guidelines error response format, which is itself the error response format used by the OData protocol
(see OData JSON Format §21.1). If you need to retain that format, the Error Response backward compatibility topic
discusses how to enable it.
ProblemDetails.Type could logically be used to model the established error Code; however, the value is supposed to
be a URI. For backward compatibility, the existing error codes will be emitted as the Code extension in Problem
Details. The Error Responses topic provides details for each well-known problem that may be returned in responses.