Umbraco 13 is now officially out and as you are reading this article I assume that you are interested in learning how you can upgrade your site to v13. The steps to upgrade an Umbraco site are usually very similar, however, with this release there is a catch!

As of Umbraco 13, you no longer need to include a Startup.cs file within your solution. This means that anyone who might want to upgrade to Umbraco 13 should also take this opportunity to get rid of Startup.cs if your current site is using one and this is where the article has you covered

Read on if you want to learn how to upgrade a site to Umrbaco v13 as well as learn how to refactor your Program.cs file 🔥🔥🔥

How To Upgrade

The first step thing that you will need to do before attempting to upgrade anything is to make sure you have [.NET 8 installed]( and you have Visual Studio patched to [version 17.8]( minimum. Also, make sure that you have a backup of all your website files and your database before you begin... you have been warned !!!

After doing this you will need to set all of the class libraries within your solution to use .NET 8 as default, you can do that like this:

Umbraco 13 Upgrade And Startup.cs To Program.cs Refactoring Guide 1

After setting your site to use .NET 8, your first task is to upgrade your .NET and Umbraco-related Nuget packages. This bit is always fun, as most of the time you will bump into errors. What will typically happen is that you try to upgrade one package, the compiler complains and you will see an error that the change will impact something else!

If this happens to you, you need to play dependency Jenga. Typically, you will need to upgrade all your .NET packages first, before you will be allowed to upgrade your Umbraco packages.

In terms of installation order, you will usually need to upgrade the Common and Infrastructure packages first, then Core, and then the Umbraco.CMS package last. The order in which you will need to upgrade things will vary on a project-by-project basis, but keep at it until everything is upgraded.

After you have upgraded all your Nuget packages, try to build the solution. If you are lucky it will build. What is more likely, is that you will now encounter coding errors. Don't panic here because this is expected.

Each version of Umbraco contains breaking changes, as does each version of .NET. Our job here is to fix any code that relies on obsolete packages. In this step, you will need to change these areas to use a .NET 8-supported approach.

For reference, Umbraco maintains a list of all breaking pages that you can find here and Microsoft also has a . NET-related one here.

After your project builds, launch your site in the debugger. When your site loads you should see a maintenance page. Go to /umbraco and you should see the installation/upgrade wizard. Log in and follow the steps. This will upgrade your database to V13.

Finally, launch your website and check it loads OK and your pages are behaving the way you want them to. You have now successfully upgraded your site. Only after your site is upgraded AND working, should you think about refactoring your Startup.cs file. Never try and refactor Startup.cs until you have successfully upgraded your site, otherwise, you will make your life harder. DO one set of tasks at a time to minimize the amount of random errors and bugs that get intorduced!!!

Refactor Startup.cs Into Program.cs

It's now time to get rid of Startup.cs for good. Before you get going, I recommend that you take a look at a vanilla Program.cs. This should give you a good reference about how your Progam.cs might look like afterwards. Below is an example of the default Program.cs that the Visual Studio Umbraco template will create when run:

A key bit within this code is the line that ensures that the Umbraco dependencies are loaded correctly:

To be super clear here, this helper is new to Umbraco 13. This means that when anyone upgrades to v13, this line will be missing and as part of your upgrade journey you WILL need to add it.

The good news is that this bit of code should be the only new code that you will need to add throughout this process. For reference, if you try to load your Umbraco site and this line is missing, this exception will be thrown:

As a quick aside, if anyone reading this is only upgrading from Umbraco v12 and you have already gotten rid of Startup.cs, it is likely that you added this code within Program.cs in order to hack the .NET pipeline to load the Umbraco dependencies:

If you are one of the few who went this route, do not forget to delete this code and replace it with a call to BootUmbracoAsync().

With the structure covered, how do we go about porting our code out of Startup.cs and into Program.cs?

How To Refactor Your Code From Startup.cs into Program.cs

The complexity of refactoring Startup.cs into Program.cs will be dependent on the complexity of the site. If you have a simple site, you will likely not have that much in your Startup.cs. If like my site, you have caching, custom redirects, and more, moving everything from Startup.csintoProgram.cs` will likely take a little longer

One issue with merging two files is complexity. Just because we can use a single Program.cs, this does not mean you should throw good design out the window. When refactoring your Startup.cs, instead of simply copying everything into Program.cs, instead, I recommend adding that code inside some new classes instead. These helper classes will ensure you end up with a lean, mean Program.cs fighting machine that is easy to understand.

To implement this pattern, I usually create a folder in my web application root and call it Startup. In this folder, I add two files. One class will be used to register services, which I name ServicesInitializer. The skeleton code for this class looks like this:

After registering services and stuff, the next step is to configure how these services run within your execution pipeline. To do this, you will typically add middleware to your pipeline. This is why my second file is called MiddlewareInitializer, whose skeleton structure looks like this:

In essence, these two classes map to the two methods in Startup.cs. All the code within ConfigureServices(IServiceCollection services) should be moved to ServicesInitializer and all the code within Configure(IApplicationBuilder app, IWebHostEnvironment env) should be moved into MiddlewareInitializer:

Following this refactoring, I should eventually be able to delete my Startup.cs, with my end Program.cs file looking like this:

WebApplication Vs Host

Another refactoring that I wanted to make when upgrading my site was converting the site from bootstrapping my application using Host.CreateDefaultBuilder() and bootstrapping my application to use WebApplication.CreateBuilder(args); instead.

When I first upgraded my site from Framework to .NET 5, I decided to use Host to bootstrap my app. In case you weren't aware, you can use both Host and WebApplication to start your application. Typically for web applications, you should use WebApplication and for non-web applications, you would normally use Host.

Originally, I used Host as it provided more advanced configuration options. When .NET 5 launched it didn't have support for things like an output cache. I needed to implement some custom things and at the time Host made more sense than Web, however, that is no longer the case. Alternatively, all the code snippets and examples on the Umbraco World use Web, so it makes more sense now for my site to use the most used path. This way my tutorials have the widest impact!

If you want to do the same, I will quickly walk you through the process. My original Program.cs looked like this:

After moving to a Web bootstrapped Umbraco site, I did not have access to the same extension methods that I previously made use of. Instead, I had to change my code to look like this:

With those changes applied, I could then delete my Startup.cs, and my upgrade journey was complete. Happy Coding 🤘