DNN Blogs

Written for the Community, by the Community

Why It’s Time to Rethink the DNN Upgrade Process

Written By Peter Donker
2025-10-22

As DNN continues to evolve, we’re increasingly relying on modern .NET libraries distributed through NuGet. This has opened the door to powerful new features and integrations — but it’s also brought with it an old and familiar problem: DLL hell. In this post, we’ll walk through why our traditional upgrade process no longer fits today’s reality, and how we’re moving toward a more robust, installer-driven approach to keep your sites stable and easier to upgrade.

The Classic DNN Upgrade Process

Historically, upgrading DNN has been simple — maybe too simple. You’d download a _Upgrade.zip package, extract it over your existing installation, restart your site, and let DNN’s built-in upgrade logic take over. During that process, all DLLs from the upgrade package would overwrite whatever was already in your bin folder. This worked fine back when DNN and its dependencies lived entirely within the .NET Framework ecosystem. But the landscape has changed.

The Problem: Modern Dependencies Meet Old Habits

With more and more features being delivered via NuGet, DNN now includes a growing number of .NET Core–based libraries, such as Microsoft.Bcl.AsyncInterfaces.dll. These libraries are often shared dependencies — used both by DNN itself and by third-party modules distributed by the community or vendors. When a module developer installs a NuGet package, it can bring along one of these shared DLLs, potentially at a newer version than the one bundled with DNN.

Here’s where things start to go wrong: During module installation, DNN smartly checks each assembly version. If a newer version exists, DNN copies it into the bin folder and updates the web.config with the appropriate binding redirect. Later, during a platform upgrade, the _Upgrade.zip process blindly overwrites DLLs — even those newer ones — with the versions included in the core package. The result? The binding redirect now points to a version that no longer exists.

Let's look at a concrete example:

  • DNN ships with the .net 8 version of Microsoft.Extensions.DependencyInjection.dll
  • You install a module that has shipped with a .net 9 version of Microsoft.Extensions.DependencyInjection.dll. The module installer now copies over this dll and updates the binding redirect to point to version 9.
  • You install a module that has shipped with a .net 8 version of Microsoft.Extensions.DependencyInjection.dll. The module installer detects a newer version has already been installed and does not copy over this dll.
  • You try to upgrade DNN by copying the contents of the _Upgrade package over your installation. Let's assume this newer version of DNN still ships with the .net 8 version of Microsoft.Extensions.DependencyInjection.dll. So now in the bin folder you have the .net 8 version.

Now your site fails to start with a big fat yellow error screen! And fixing this isn’t easy. It often requires manual inspection of the bin folder and web.config, tracking down which assemblies were replaced incorrectly. I know because it's happened to me.

As DNN continues to modernize — adding features that depend on multiple .NET libraries like Serilog, for example — this problem compounds. A single upgrade could involve 15–20 DLLs, dramatically increasing the risk of conflicts and broken sites.

The Solution: A Smarter, Safer Installer

Fortunately, we already have the foundation for a better solution. Starting in DNN 10.1, Brian Dukes submitted an internal installer designed to handle upgrades in a more intelligent, modular way (many thanks to him for this addition). The underlying idea is to make all assemblies from DNN go through the same process as a module's assemblies would. It works by placing the _Upgrade zip file in App_Data/Upgrade. The Upgrade zip file is extracted and a "mini installer" is created to do this for every dll in the bin folder of the distribution. This process means that "old" don't get copied in and newer ones do and the assembly redirects get set correctly.

Until now there has been no clear UI for this to kick off. I’ve been working on the UI for this installer, and I believe it’s shaping up to be the future of how DNN upgrades are performed. You can upload the DNN zip file to your site and kick off the upgrade process from there. As an added bonus this will also work with the Install package as the installer makes sure to filter out the files it shouldn't copy.

The Next Step: Enforcing the New Upgrade Path

To make this process reliable for everyone, we need to take one more important step: Stop distributing _Upgrade.zip packages. As mentioned above the installer can also work with the _Install package. No longer making this available will mean everyone will need to go through the UI to upgrade. Users familiar with the old process will immediately notice the change — and when they look for an explanation, we’ll point them to the new, safer, UI-driven upgrade process. This ensures consistency, eliminates a major source of upgrade-related errors, and future-proofs DNN as we continue to integrate modern .NET technologies.

Wrapping Up

As DNN evolves, so must our tooling and habits. The traditional file-copy upgrade process served us well for many years, but it’s no longer compatible with the complexity of today’s .NET ecosystem. By moving to an installer-based approach — and retiring the _Upgrade.zip packages — we’re taking an important step toward a more stable, predictable, and developer-friendly future for DNN.

Links:

 

Total: 8 Comment(s)
Where/how can I test?
Thursday, October 23, 2025 ·
That is tricky. When you go to a PR on Github you can drill down to get to the built assets. You do this as follows: 1. Open the PR in your browser, 2. Click on the "Checks" tab at the top, 3. Click on the link under the build "0 errors/xyz warnings", 4. On the big panel with my mug shot and various stats find "1 published" and click on that, 5. you'll see just one line "Artifacts" with a tiny menu at the end with "Download artifacts". That zip includes all the zips you need.
Thursday, October 23, 2025 ·
But beware: to properly test it (the complete upgrade process), you need a fake package that is a higher version. For this you need to actually build DNN locally with a higher version number. This is not for the feint of heart.
Thursday, October 23, 2025 ·
Changing the dotnetnuke.dll version info with https://www.angusj.com/resourcehacker/ did not do the trick ;)
Thursday, October 23, 2025 ·
This sounds great Peter! Thank you and thanks to Brian Dukes!!!
Monday, November 3, 2025 ·
Wonderful - such amazing progress!
Friday, November 28, 2025 ·
I really love this! Thanks @Peter!
Tuesday, January 6, 2026 ·
Thank you for this critical forward-thinking update, Peter, Brian, and everyone else who contributed this upgrade upgrade. 😎🤙🏽🤙🏽
Monday, March 9, 2026 ·

Would you like to help us?

Awesome! Simply post in the forums using the link below and we'll get you started.

Get Involved