Within this guide, you will gain access to a proven plan that will take your current Episerver CMS-powered website and upgrade it to the latest version, now known as Optimizely CMS.

The hardest challenge within this upgrade path is converting your code from .NET Framework to .NET Core/ASP.NET 5/ASP.NET 6. Within this guide, I will share my opinions about how you should approach your upgrade plan. You will learn the steps you will need to take, the things that will break, and the tools you can use to speed up the process.

To save myself from having to write .NET Core/ASP.NET 5/ASP.NET 6 everywhere, I will use the term .NET Core to refer to the new world. If you were looking for the BEST Optimizely upgrade guide then today is your lucky day 🔥🔥🔥

ASP.NET 5 or ASP.NET 6

When considering an upgrade, your first question should be which version of .NET should you upgrade into. As of writing, the CMS does not officially support .NET 6, however, if you use it it will work. There are two good business benefits of picking ASP.NET 6. First, Microsoft is providing LTS (long-time support) for v6. If you are unaware of what this means, you can learn more about that here. Microsofts support period for ASP.NET 5 has already expired, so picking the long-term support version is sensible.

The other reason for using ASP.NET 6 is performance. ASP.NET 5 runs significantly quicker than .NET 4 Framework. Microsoft then claims ASP.NET 6 is 40% more performant compared to ASP.NET 5.

In terms of code, the only big difference between .NET 5 and .NET 6 is the new minimal API syntax. In ASP.NET 5 we have Startup.cs and Program.cs. Within .NET 6 Startup.cs has been deprecated. You can still use it if you like, however, in the new world you only need Program.cs. Personally, I like having a Startup.cs as it leads to a slightly cleaner codebase, however, as always do what makes you happy 👄😘👨‍❤️‍💋‍👨💋❤💖❣💓💝💛💚💙💜💕💞💘

Be stale or go fresh?

The next decision that you will need to make when upgrading is simple, do you start from scratch or do you try and convert your current website into .NET Core? When I say start from scratch, that does not necessarily mean deleting all your old code and HTML and restarting.

If your website is built using the .NET Web Forms framework you will need to rebuild the solution. Web forms do not work in the new world. If you need to completely change the look and feel of your website and its content structure, again re-building from scratch makes sense.

The other consideration of whether to go stale or fresh is slightly more subtle. Starting with a blank canvas for large projects can often significantly reduce your upgrade timeframes.

Over the years, I have performed well over 50 major CMS upgrades using a variety of different CMS solutions. Out of these experiences, I typically found that the slowest and more painful processes are the ones where you are forced into a big bang explosion of things breaking at the same time 💥.

Any process where you are suddenly presented with hundreds of errors at the same time is frustrating and slow. The issue with a fix-everything at the same time process is that it usually takes a couple of days just to get your project to simply compile.

During this get-it working phase, you will exclude files from the project, comment-out breaking code and perform general hacking activities on anything that is broken. In essence, you do whatever it takes to get the solution to build again.

During this hacking period, you are also unable to test anything. The result of this is that when you eventually get the solution to build, nothing works and then you need to try and fix things. Often you forget what you have changed or commented out, resulting in lots of trial and error.

On top of fixing broken code, as you are going to .NET Core there are other considerations. Project files need upgrading, some of the existing files will need to be copied into new locations, new files will need to be created, and old files removed before the solution will work. If you are really unlucky you may need to try to run Framework and Core libraries simultaneously 😱

Instead of adding more fuel to the fire, by making yourself fix code and config at the same time, you should aim to make your life as easy as possible. Any processes where you can move a little slower, moving one step at a time will make your life much easier and the process more enjoyable, so how do you move slower?

If you want to go from CMS 11 to CMS 12, I recommend that you start from a clean slate. When I say clean slate, I am not saying throw out all your old code. Instead, what I mean is to create a new vanilla CMS 12 .NET Core solution. The structure of this new solution should exactly mirror your old solution. It should mirror the class library structure, with the same naming conventions and namespaces. Doing this should take you about 15 minutes.

After creating an empty solution, the strategy is to get the site working one page at a time. You will do this by copying the minimal amount of code from old into new. After copying the code, you then upgrade it from Framework to Core and fix everything there and then. After you have one page working, you rinse and repeat the process until all your code is migrated and working.

If you have never tried this type of refactoring approach before, it may feel like it will take more effort and consequently take longer, however, from my experience, being able to make constant little steps always results in the job getting done quicker. If you disagree with me, you can follow the approach that makes you happy 😊

If you are still unconvinced about this approach, I recommend you consider these points:

  • Not all Episerver community packages have been upgraded to CMS 12, all this code will break
  • All the caching code will need to be completely re-written
  • web.config will not work
  • global.ascx will not work

If you try to upgrade your current solution, before you can get a single page to work you will need to fix all these things at the same time. Starting from blank you mean that you will get the majority of the correct config for free using the Optimizely installer!

Optimizely CMS 12 Upgrade Plan

Assuming I have convinced you that starting with a blank solution makes sense, your overall upgrade plan will look something like this:

  • Backup your current Episerver code and database, make sure it is committed and pushed
  • Create a blank database for your new Optimizely website and restore your current database to it
  • Create a brand new vanilla Optimizely website. If you are unsure of how to do this, some legend created an EPIC installation tutorial here. Make sure you use the same namespaces etc.. as old
  • Create corresponding class libraries using the correct version of .NET
  • Copy all the old sites' Javascript, CSS, and Assets (as well as the Episerver media folder) from old into wwwroot
  • After successfully creating a new site, open up appsettings.json. Change the EPiServerDB connection string to target the new database you created above
  • Run the database upgrade wizard to upgrade your database to CMS 12 (instructions on how to do that below)
  • After successfully upgrading the database, try and log into the backend with your admin account
  • Pick the simplest page type on your site and aim to get it working in the new world. I do not recommend trying to get the homepage working first. The homepage tends to be pretty complex and interconnected. The first page-type I tend to pick will be something simple like a content page.
  • Copy the code related to the page from old to new. This will include the controller, view model and view. Instead of manually copying the files over using Windows Explorer, I suggest you use a diff tool like WinMerge or BeyondCompare to make the process quicker.
  • Comment out any references within the view file to the master layout. You want to focus on getting the page working on its own quickly. You do not want to worry about getting the page AND the header AND the footer working at the same time if you can avoid it.
  • Compile the solution and fix bugs. This step will involve a lot of refactoring. You may consider using the Microsoft upgrade wizard and the Episerver upgrade wizard now.
  • When the page is finally working, add the reference to the layout back within the view. Copy all the header and footer-related code from the old site to the new site.
  • Compile, test, refactor and fix the issues
  • If you encounter issues, you may want to enable logging or at least level it up, learn more about that here
  • After the page and header and footer are working, repeat the process. Pick another page type, rinse and repeat
  • After getting all the pages working, add any caching-related code to the solution
  • Add deployment transforms, redirects, routing, etc...
  • Install plugins like Sitemap, RSS feeds, Content Manager, etc...

By this stage, you should now have a fully upgraded Optimizely CMS 12 website that works 😊

Upgrading Considerations And Coding Issues

The largest investment of your time during an upgrade will be the refactoring effort. Unfortunately, there is no magic silver bullet for automatically converting your .NET Framework code to work in CMS 12. Expect to be faced with refactoring challenges ranging from small syntax updates to big architectural changes such as changing the DI container and introducing view components.

To get an understanding of what you can expect to break, you can check out the official Optimizely breaking changes document called Breaking changes in Content Cloud (CMS 12).

As you can see from that page a lot has changed. NuGet package names, the underlining DI container, ServiceLocator, the logging provider, routing rules, where the config lives, and a whole bunch of other stuff! To help upgrade this broken Optimizely code, there are two upgrade tools that you can make use of.

The first tool was created by Microsoft and it is called the Microsoft Upgrade Assistant. This tool will automatically convert your solution and code to .NET Core.

The second tool is the Optimizely upgrade-assistant-extensions available for download here. This extends the Microsoft wizard with Optimizely related fixes.

Using both of these tools is simple enough. To install the Upgrade Assistant, you can use this command from a terminal:

After you have installed the upgrade assistant, navigate to a folder that contains a project file within your solution in the terminal and then use this command:

Replace JonDJones.Website.Core with your project name. During the upgrade, you will need to use the keyboard to tell the wizard what it should do. All you really need to do is keep banging the number 1 key until it completes:

Microsoft Upgrade Assistant

If you want to enhance this tool to also apply Optimizely fixes, you should install the Episerver upgrade assistant extensions. To do that go to this page and download the files. To run the Optimizely upgrade assistant from the terminal, you can use this command:

I copied the upgrade files onto my C drive within a folder called devtools. The tool will give you additional upgrading options like:

  • Convert project file to SDK style
  • Clean and update NuGet packages
  • Clean code, e.g. remove references to 'System.Configuration', update TFM
  • Replace strings in source files
  • Upgrade app config files
  • Add program.cs and start.cs
  • Fix known Episerver issues
  • Add template files

Installing the extension will give you lots of options, you will not want to use them all so expect to spend a little more time figuring out what you want to apply.

Optimizely Upgrade Assistant

For example, in a class library, you will not want a program.cs created. In an ASP.NET 6 project, you may not want a startup.cs. The wizard will let you upgrade code quicker, however, I am still sceptical of using it.

Using a code upgrade wizard will mean that magic is happening in your solution. You may not exactly understand what has been fixed and why. As the project lead, even though it may take you a little longer, manually fixing broken code will give you more knowledge about your codebase. This knowledge can be very handy when a production website goes down! Think wisely if you want to cheat, or, go quickly!

There is also another hacky shortcut that you could consider to reduce the amount of code that you need to refactor. There is a package called EPiServer.Cms.AspNetCore.Migration. This package provides access to now some obsolete types and even promises to make the switch from web.config to package.json easier. The promise of the package is less code to refactor. In my opinion, one part of re-platforming is to improve code quality not sweep it under the carpet!

I do not recommend you use this package, as in the long run you are doing yourself no favours. copying old crud from old to new is the first broken window in the new world.

When upgrading, expect to see build issues everywhere, especially in:

  • Controllers (minimal)
  • Dependency injection re-configuration (minimal)
  • Moving partial view references to view components (medium)
  • Performance tweaks (high)
  • Config fixes due to the move from web.config to appsettings.json
  • Moving code from global.ascx into Program.cs
  • Enabling new middlewares/packages
  • Syntax changes due to obsolete types, like IHtmlString
  • Removing code that references CMS 11 packages that are no longer supported
  • Refactoring any code that references System.Web
  • Refactoring any code that references HttpContext.Current

As you can see this potential list of nastiness is pretty long and this is also not an exhaustive list.

Optimizely CMS Upgrading Tips

Database Upgrade Wizard: The easy way to upgrade the database from old to CMS 12 is via the CLI. You can use this command (thanks Luc Gosso):

Easy Access To A Working Optimizely CMS 12 site: When I was upgrading my site, I found that having access to a working Optimizely CMS 12 site was helpful. You can quickly copy code into it and see if it works or not. I used my starter kit for this process. If you want to do the same, you can access that site from my Github for FREE here. If you do want to use my site, you can also use the official Optimizely sample site called Foundation from here.

Tooling: Microsoft has built a Visual Studio extension called the Portability Analyzer. The tool will analyze your code and then generate a report that details all the compatibility issues between your current framework and a selected target framework. Using this tool before you start the process will give you a better indication of how long the upgrade path might be. You can download the Portability Analyzer here. You can also check which packages are compatible from Framework to Core using the .NET API Catalog .


There is no painless way of ripping off the CMS upgrade bandage. The code fixes and tweaks that you will need to make in order to successfully upgrade your website will be pretty substantial. The more complex your current solution, the more code that you will need to refactor. Speaking from experience, following this plan will make the process as easy as it can be. Good luck and Happy Coding 🤘