Migrating Rest API with Swagger & URL based versioning from Asp.Net core 2.2 to 3.1

In one of my earlier post Integrating Swagger with URL based Asp.Net core API versioning I have added swagger to ASP.Net core 2.2 WebAPI. At this post, I am upgrading my existing Asp.Net core 2.2 API project to Asp.Net core 3.1.

Tools

I am using Visual Studio 2019 community edition and Git for source control. Moreover, I am migrating to ASP.Net core 3.1 for one of my GitHub repo

Steps to migrate from 2.2 to 3.1

First I have changed the TargetFramework from 2.2 to 3.1 and build the project

<TargetFramework>netcoreapp2.2</TargetFramework>
changed to
<TargetFramework>netcoreapp3.1</TargetFramework>

And then, I have got the following error

Could not copy "C:\...\netcoreapp3.1\RestApi.Example.dll" to "bin\Debug\netcoreapp2.2\RestApi.Example.dll". Exceeded retry count of 10. Failed. The file is locked by: ".NET Core Host (6508)"    RestApi.Example.Tests...

Solution: after restarting the visual studio, the solution builds successfully. And then I ran my tests. Although the unit tests passed, integration tests are failing and the reason is

System.TypeLoadException : Method 'ApplyAsync' in type 'Microsoft.AspNetCore.Mvc.Routing.ApiVersionMatcherPolicy' from assembly 'Microsoft.AspNetCore.Mvc.Versioning, Version=3.1.0.0, Culture=neutral, PublicKeyToken=xxxx' does not have an implementation.

I found this GitHub issues 504 for aspnet-api-versioning, which basically suggests tp use the preview version 😐 So I have upgraded the packages

To upgrade NuGet packages I open the Manage Nuget packages for the solution and then go to the update and also include prereleases, check the following image

The NuGet package manager for the Solution on VS2019

Build Errors

After successfully updating all the above packages, I have built the project and got the following 5 errors

  1. 'SwaggerDefaultValues' does not implement interface member 'IOperationFilter.Apply(OpenApiOperation, OperationFilterContext)'
  2. YamlDocumentFilter' does not implement interface member 'IDocumentFilter.Apply(OpenApiDocument, DocumentFilterContext)'
  3. The type or namespace name 'Info' could not be found (are you missing a using directive or an assembly reference?)
  4. The type or namespace name 'Operation' could not be found (are you missing a using directive or an assembly reference?)
  5. The type or namespace name 'SwaggerDocument' could not be found (are you missing a using directive or an assembly reference?)

does not implement interface member ‘IOperationFilter.Apply(OpenApiOperation, OperationFilterContext)’

In the later version, IOperationFilter signature is changed. It is no more Operation type.

public interface IOperationFilter {
 void Apply(OpenApiOperation operation, OperationFilterContext context);
}

So, I have also change the type to OpenApiOperation which is in the Microsoft.OpenApi.Models namespace. And I have removed the Swashbuckle.AspNetCore.Swagger namespace from the class.

After I fix this error, another error showed up in the same file The type or namespace name 'NonBodyParameter' could not be found. I have found this open issue 1373 as of today. For now, I have just removed uses of NonBodyPArameter

foreach (var parameter in operation.Parameters.OfType<NonBodyParameter>()){
  ...
  if (parameter.Default == null){
    parameter.Default = routeInfo.DefaultValue;
  }
  ...
}
convert to 
foreach (var parameter in operation.Parameters){
  ...
  //if (parameter.Default == null) {
  //    parameter.Default = routeInfo.DefaultValue; 
  //}
  ...
}

Now, I have three more errors to fix. However, the changes above also fixed the following error

The type or namespace name 'Operation' could not be found

does not implement interface member ‘IDocumentFilter.Apply(OpenApiDocument, DocumentFilterContext)’

IDocumentFilter signature has been changed. Instead of SwaggerDocument we need to use OpenApiDocument. And also, the namespace has been changed from Swashbuckle.AspNetCore.Swagger to Microsoft.OpenApi.Models

This also get rid off the error The type or namespace name 'SwaggerDocument' could not be found

The type or namespace name ‘Info’ could not be found

After building the project, I have a pair of errors to fix. But the good news is its the same error 'Info' could not be found

In the SwaggerSettingsclass, the Info type is used in two places. In addition, I noticed the namespace Swashbuckle.AspNetCore.Swagger has been dimmed and telling me it’s not in use. I have changed the type to Microsoft.OpenApi.Models.OpenApiInfo. Now the project builds with no errors. However, I noticed that the type of TermsOfService has been changed from string to Uri

Remove obsolete package references

As the solution builds, I have noticed that package Microsoft.AspNetCore.App has not been loaded.

According to the migration step, I have to remove this obsolete package.

Warnings

At this point, projects are building with errors, but few warnings below have started to appear

  1. Using ‘UseMvc’ to configure MVC is not supported while using Endpoint Routing. To continue using ‘UseMvc’, please set ‘MvcOptions.EnableEndpointRouting = false’ inside ‘ConfigureServices’.
  2. ‘CompatibilityVersion.Version_2_1’ is obsolete: ‘This CompatibilityVersion value is obsolete. The recommended alternatives are Version_3_0 or later.’
  3. ‘IHostingEnvironment’ is obsolete: ‘This type is obsolete and will be removed in a future version. The recommended alternative is Microsoft.AspNetCore.Hosting.IWebHostEnvironment.

Error: ‘Endpoint Routing does not support ‘IApplicationBuilder.UseMvc(…)’

This is required because MVC must know whether it can rely on the authorization and CORS Middleware during initialization. An analyzer is provided that warns if the app attempts to use an unsupported configuration.

Use MVC without Endpoint Routing

Therefore, I have added options => options.EnableEndpointRouting = false to services.AddMvc() though the warning is showing for UseMvc

‘CompatibilityVersion.Version_2_1’ is obsolete

To get rid off the warning, I have modified the set compatibility version to Latest

.SetCompatibilityVersion(CompatibilityVersion.Latest)

IHostingEnvironment has been depreciated

I need to change IHostingEnvironment to Microsoft.Extensions.Hosting.IWebHostEnvironment see this announcement.

Moreover, For more details about migrating Startup.Configure please check here

In the end

Finally, I can see the swagger UI page again, check the screenshot below

Swagger UI for OpenAPI 3.0

Voila!! OAS3 has started to appear on my swagger UI. In addition, if you want to download check my Github repository

Whether I have missed something or this does not work for you please leave a comment

I would like to hear your thoughts