Upgrading .NET Core 2.2 Web Api to .NET 5 Web API

It's the one thing you dont wanna do, but it has to be done! I'll get you through the worst pitfalls of upgrading your existing Web API's to .NET 5!

Post 3
Prerequisites

Before we get into the detail's, let's make sure you are ready to work with .NET 5. Let's headover to Microsoft and download the latest SDK ( https://dotnet.microsoft.com/download/visual-studio-sdks?utm_source=getdotnetsdk).

Once you have installed the net .NET 5.0 SDK, we need to ensure our Visual Studio is up 2 date otherwise you will not be able to find .NET 5.0 in your target framework under project settings. This can be done by going to the help tab and choosing 'Check for updates'

Alrigt at this point we can assume we are ready to proceed with upgrading our Web API and underlying/referenced projects.

Upgrading!

The first thing we need todo is change our project target to .NET 5, and then its time to dig into our projects configuration file. As stated in previous post's Swashbuckle / Swagger is a must use on Web API's, so I also assume that you are utilizing this little nuget gem. It would seem that Microsoft agree's with us, as Swashbuckle/swagger is now part of the .NET Web Api projects out of the box. With that said we can safely remove our swashbuckle nuget packages, as we also need to setup the built in version abit different. After removing the Swashbuckle nuget package, we can just refeere the package reference in our project configuration file, in addtion I also took the liberty to update my Newtonsoft Json Nuget to the latest version.


<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
    <ProjectReference Include="..\JaisEdelmann.Blog.Core\JaisEdelmann.Blog.Core.csproj" />
  </ItemGroup>

</Project>
Startup.cs

With that out of the way, let's head over to startup.cs, as we have quite a few things to change here aswell. When you change your target aritechture Visual studio will try and help you get your existing code working, but I decided to just upgrade directly to the latest way of settings up new Web API's as I didnt want to utilitze obsolete compatibility modes, now that we are upgrading might aswell do it right.

Let's first look at ConfigureServices, as you can se the implementation is a littlebit different when adding our Swagger service other than that everything is the same.


 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Jais Edelmann Blog Api", Version = "v1" });
            });

            services.AddSingleton<Interfaces.IdbService, Services.dbService>();
        }

Thing's get a little more interessting when we when look at our Configure section as we have now replaced IHostingEnvironment with IWebHostEnvironment as IHostingEnvironment is now obsolete. In order to access IsDevelopment bool we need to reference 'Microsoft.Extensions.Hosting'.


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Jais Edelmann Blog Api");
                    c.RoutePrefix = string.Empty;
                });
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
Controllers and routes

At this point I'll assume that you have a working application again, however you might experience that when you hit your frontend, you are greeted by 'Failed to load API definition.' If you review your debug window in Visual studio , chances are you are seeing the following message: 'Actions require a unique method/path combination for Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround'. This is because you are most likely using the incorrect method decoration, but it's actually very straight forward now. Let's look at how I setup my BlogPostController in this example.


using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;

namespace JaisEdelmann.Blog.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BlogPostController : ControllerBase
    {
        private readonly Interfaces.IdbService _dbService;
        public BlogPostController(Interfaces.IdbService dbService)
        {
            _dbService = dbService;
        }
        [HttpGet]
        public ActionResult<IEnumerable<Core.Models.BlogPost>> Get()
        {
            var db = _dbService.GetDb("db.json");

            return db.blogPosts.OrderByDescending(x => x.CreateDate).ToList();
        }

        [HttpGet("{Id}")]
        public ActionResult<Core.Models.BlogPost> Get(Guid Id)
        {
            var db        = _dbService.GetDb("db.json");
            var result    = db.blogPosts.SingleOrDefault(x => x.Id == Id);

            if (result == null)
                return BadRequest($"BlogPost with Id '{Id}' not found");

            return result;
        }
    }
}

For this example we will have 2 endpoint's now, one would be /api/blogposts which will return all existing blogposts, /api/blogposts/id will return a specific blogpost with that id unless it's unable to find that specific blogpost.

That's it, your done! your Web API should now be running .NET 5, thanks for reading!