How To Upgrade ASP.NET Core 2.1 To ASP.NET Core 3.1 version

Introduction

This article provides the guidelines to upgrade ASP.NET Core 2.1/2.0 (or lower versions) to 3.1. .Net Core 3.1 has long-term support and if you are using a 2.0/2.1 or lower .NET Core application and need to upgrade it, this write-up will help you.

The very first step for migration is changing the target framework. For this: right-click on Project-> properties and then in project properties select the target framework to 3.1 as illustrated below.

How to Upgrade ASP.NET Core 2.1 To ASP.NET Core 3.1 version

Alternatively, you can change the target framework from .csproj file changing the target framework to netcoreapp3.1.

Right-click on the project and then click on Edit project file.

Then change the target framework to netcoreapp3.1.

How to Upgrade ASP.NET Core 2.1 To ASP.NET Core 3.1 version

Once you change the .net core version from 2.1 to 3.1 from Solution properties, then build the solution. Some packages will be restored and upgraded automatically. You may get number of errors in the solution but with that, there will be some suggestions showing what you need to do after upgrading the solution framework. Based on the suggestion, you can resolve the issue; however, in this article basically, we will discuss the Startup. cs file changes which are very crucial, and will throw errors even if you have no errors after building the solution too.

Guideline 1

You may get the below error while running the application even if your solution builds successfully.

How to Upgrade ASP.NET Core 2.1 To ASP.NET Core 3.1 version

When we continue to run the project, the page will be loaded with the below error message.

How to Upgrade ASP.NET Core 2.1 To ASP.NET Core 3.1 version

Let’s move to the solution of the above error. Thing is after migration to ASP.NET Core 3.1, we have to use UseEndPoints() instead of UseMVC();

Inside Configuration() method of Startup.cs file, we need to change the below code.

app.UseMvc(routes => {
    routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});

To

app.UseEndpoints(endpoints => {
    endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});

Guideline 2

You may get the below error,

Error: EndpointRoutingMiddleware matches endpoints setup by EndpointMiddleware and so must be added to the request execution pipeline before EndpointMiddleware

If you get an error like the above then, follow the below suggestion.

We have to use app.UseRouting(); inside the Configuration() method of Startup.cs file

app.UseRouting();//error message suggested to implement this

Guideline 3

Additionally, If you have implemented SignalR then you will get information or warning messages like this :

How to Upgrade ASP.NET Core 2.1 To ASP.NET Core 3.1 version

In ASP.NET Core 2.1 application, SignalR is written as shown below which resides inside the Configuration() method of Startup.cs file.

app.UseSignalR(routes => {
    routes.MapHub < ChatUpdaterHub > ("/chat-updater");
});

However, in ASP.NET Core 3.1 it should be implemented with endpoints as illustrated in the below code.

app.UseEndpoints(endpoints => {
    endpoints.MapHub < ChatUpdaterHub > ("/chat-updater"); //Signal R implementation
    endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});

Code of Startup.cs class of .NET Core 2.1 is

public class Startup {
    public IConfiguration Configuration {
        get;
    }
    public Startup(IConfiguration configuration) {
        this.Configuration = configuration;
    }
    public void ConfigureServices(IServiceCollection services) {
        services.AddSingleton(defaultEndpointsSettings);
        services.AddDistributedMemoryCache();
        services.AddTransient < ApiRequester > ();
        services.AddHostedService < FetchingBackgroundService > ();
        services.AddMvc();
        services.AddSignalR();
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
        if (env.IsDevelopment()) {
            app.UseDeveloperExceptionPage();
        } else {
            app.UseExceptionHandler("/Home/Error");
        }
        var cachePeriod = env.IsDevelopment() ? "600" : "604800";
        app.UseStaticFiles(new StaticFileOptions {
            OnPrepareResponse = ctx => {
                ctx.Context.Response.Headers.Append("Cache-Control", $ "public, max-age={cachePeriod}");
            }
        });
        app.UseSignalR(routes => {
            routes.MapHub < DataUpdaterHub > ("/ws-updater");
        });
        app.UseMvc(routes => {
            routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

When we upgrade the same project to .Net Core 3.1 Startup.cs class should be like this,

 public class Startup
    {
        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Environment { get; }
        public Startup(IConfiguration configuration, IWebHostEnvironment environment)
        {
            this.Configuration = configuration;
            Environment = environment;
        }

        public void ConfigureServices(IServiceCollection services)
        {            
           
            services.AddSingleton(defaultEndpointsSettings);
            services.AddDistributedMemoryCache();
            services.AddTransient<ApiRequester>();
            services.AddHostedService<FetchingBackgroundService>();
            services.AddMvc();
            services.AddSignalR();
           
        }

        public void Configure(IApplicationBuilder app)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            var cachePeriod = Environment.IsDevelopment() ? "600" : "604800";
            app.UseStaticFiles(new StaticFileOptions
            {
                OnPrepareResponse = ctx =>
                {
                    ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
                }
            });            
            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<DataUpdaterHub>("/ws-updater");
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Microsoft Recommendation

Microsoft’s recommendation for migration to .NET Core 3.1 is:

  • Add UseRouting()
  • Sequence of UseStatisFiles(), UseRouting(), UseAuthentication() and UseAuthorization(), UseCors() and UseEndPoints() should be in following order

Conclusion

This article described the guidelines to upgrade the .NET Core from 2.1 (or lower versions) to 3.1 with sample code and examples of errors and how to resolve them. I hope it will help you to update your application from lower framework to upper with long-term support.