From Umbraco v7 to Umbraco v9 – Part 2

If you’ve not already read part 1 which involved going from v7 to v8, you can read this in the previous blog entry.

Part 2 – Getting from v8 > v9

While I had intended to continue on with the migration to v9 the very next day after getting the project database on to v8, stuff inevitably got in the way. This wasn’t actually a bad thing in the end though, as during the extra few days delay Beta 4 of v9 was released, meaning I could do it to an even newer version of Umbraco than originally planned.

Step 0 – Ensure all the .net core/.net 5 stuff is installed
Okay, I’ve mentioned this as a ‘step 0’. I’ve been doing all of this with Visual Studio 2022 preview, which being bleeding edge pretty much comes with all the newest Microsoft .net gubbins from the outset. Had I still been doing all this on VS 2019, it’s possible I’d have had to install some extra pieces here first for .net 5.

Step 1 – Get a fresh Umbraco v9 project going
As this is all pre-release software at this stage, the setup process for bringing up a fresh instance has quite a few specific steps on the command line that need to be run, rather than just being able to grab it straight from nuget into Visual Studio like normal. However they have an excellent guide for this documented on the Umbraco site which I was able to follow – or at least for the shortest amount of time possible until I was able to ditch the command line and drop back to the IDE (sorry, personal preference there!). Once all the files were in place in the solution, I fired up the debug mode just to check the fresh installer would come up – which it did, and at blistering speed. I didn’t need to actually go through the installer though.

Step 2 – Connect v9 to the v8 database
I copied the v8 connection string out of the stepping stone project created earlier and fired up the debugger for the v9 project once more. Rather than the default installer, the login prompt popped up which is always a good sign. I popped in my existing v8 login details and immediately up came the upgrader wizard. This was a very swift upgrade as I’m led to believe so little has changed between v8 and v9’s database, and in next to no time we were to the v9 admin. Now complete with all the content brought through all the way from 7.7. A bit of quick spot checking revealed some very snappy content trees. It was a bit sluggish at initially opening one or two items in more detail, but that seemed to go away very quick so I’m going to put that down to just having to build back up some things internally first.

Step 3 – Update Models Builder configuration
With all the content there, I decided it was time to see if I can get a basic template outputting something on the front end too. To do this, first of all I needed to bring across the Models Builder config, which if you remember my previous blog entry I’d mentioned had been sort of half-heartedly used in the original v7.7 copy. Model modes have been recently updated in v9 with new naming to replace the old ‘AppData’ style naming in use meaning a little bit of remapping was needed for this setting. In the end I replaced ‘dll’ (which hasn’t been available in the embedded version of Models Builder for some time anyway) with the new ‘SourceCodeAuto’ as this seems the closest to my way of developing. I also configured my models folder to use a custom location, and added my own Namespace. I hadn’t seen these two documented, but it’s quite logical to work out how the structure of how settings in v9 are laid out relative to how they were in v8.

Models Builder Config

After setting all that, I re-ran the debug mode and tried to build some models from inside back office (auto should normally do this on change going forward). This was worryingly quick when clicked, so experience taught me to naturally assume this meant it had failed. But to my amazement, all model class files were indeed generated perfectly in the chosen folder with full namespaces. Previously in a .net Framework project I would wildcard include folders for model classes by manually editing the csproj file in a text editor. But changes in .net core projects for including files mean this is no longer needed for v9 and I could just compile models straight in to the project.

Step 4 – Build out a concept view
At this point, I borrowed a homepage view from waaaay back in the v7 project. Although the intention is to rebuild this properly, for the sakes of testing this it seemed acceptable enough. Surprisingly there wasn’t too much I actually needed to change to make this work in v9.
1) Update a few namespace references.
Umbraco.Web.PublishedContentModels became Umbraco.Cms.Web.Common.PublishedModelsand
Umbraco.Web.Mvc.UmbracoTemplatePage became Umbraco.Cms.Web.Common.Views.UmbracoViewPage
2) I removed a load of lookup code which depended on some likely overengineered bespoke caching in v7 built based off publish time events. Instead this was just simplified to call content directly from Umbraco 9’s content cache relying on crude hardcoded string document names and liberal use of ‘Descendents of Type’ in Linq. Wisdom says this is a hideously inefficient way to do things as it has to traverse several thousand nodes here, but this is all something which will be replaced later. And was really here just as a good test of performance.

Homepage view before snippet (from Umbraco v7)
Homepage view before snippet (from Umbraco v7)
Homepage view before snippet (from Umbraco v9)
Homepage view after snippet (from Umbraco v9)

3) After doing the main homepage view, I realised there were a few partial views it used too, so I copied these over from the v7 project and replaced the same namespaces as above.
4) Finally I replaced some field references in the partials. Some of these were still using the old ‘Model.GetPropertyValue’ style rather than using strongly typed model properties. But for the sakes of proving this works, I just mapped this to the equivalent in v9 which is ‘Model.Value’ (as it was in v8 too). This is something that will need rewriting to use models properly in the future. But again, this is enough to just to prove it works!
5) I also had to include the overall layout view, minus a few things commented out in the header and footer, and finally copied in some css and js assets and existing media library files to the wwwroot folder in the project (where static assets live in a .net core web application)

Step 5 – Did it work?
Well… nearly! With all the views updated I fired up the debugger again… and instantly got the infamous ‘x is not a valid UDI error’, which is caused when internal pickers still store values somewhere as integers rather than the newer UDIs. I have had this before on Umbraco 8 after a content migration though, and found it can usually be fixed by republishing some offending nodes. So all it took was a quick homepage republish from back office and we had lift-off! Up came the migrated homepage, calling in some actual content. And all of this loaded within a matter of seconds, in spite of the large size of the content tree involved, and the poorly-optimised LINQ querying mentioned before. It’s inconclusive on such a small page as to whether it’s just been able to do some sensible discarding internally and performance limits here would show up more on more involved output. But considering I’d intentionally made no optimisation attempts whatsoever here with some of the queries, this is an impressive start.

Screengrab of the homepage running off v9 outputting real CMS content
Homepage running off v9 using real CMS content

What’s next?

I’m sure you’re used to reading in articles about how ‘Hey, I got all this working in 15 minutes’. I’m not going to do that. Honestly it probably took me about 3 hours for all this, with more time spent on the initial v7 > v8 part than on the v8 > v9 bit. But even that seemed quite light given the levels of update involved here.

However this is only the very small first step of a much bigger process. To do this properly, the entire front end of this project and things like models and events will need properly rebuilding to v9 standards (which is more of a task as some of the current solution wasn’t even up to v8 standards). That said, a lot of my previous custom c# was involved in improving speed and caching when running the site on v7 and this is something which may not even need migrating. v8 had already seen some huge improvements to internal caching and performance over v7, which a previous blog post on here will mention I’d already been wow-ed on a talk on from Paul Seal and Tim Payne at Umbraco Spark 2020. There have been several further releases of v8 in the year since then, and Codegarden 2021 also included some presentations showing further impressive boosts just going from v8 to v9 and onto the new .net 5. So I’m excited to see what sort of performance boosts I will get once its fully fleshed out, before even needing to consider whether to roll out my own custom things.

Currently I’m aiming to have a fuller rebuild of the frontend side of things largely in place for when the Release Candidate comes along so the whole site can go live to the public shortly afterwards. Time will tell if that actually happens given the RC is so imminent now, but if it does I’m sure there’ll be a part 3 blog post on here in the future!