Welcome to DNN Sharp Blog


... Our fun way to keep you on top of what's happening in our world

Fix the Newtonsoft error on DNN 9.2 upgrade

DNN Sharp modules (and most probably others too) rely on Newtonsoft dll to run properly and the Newtonsoft 7.0 version that was available in older DNN versions was not enough. This is the reason why we added our own assembly binding in the web.config file so that we know for sure that the needed libraries are being deployed and correctly referenced so that the modules will properly function.

Along with the DNN 9.2.0 update, when the Newtonsoft library was also updated, a lot of our clients experienced problems upgrading the DNN version which resulted in a Newtonsoft.json.dll error.

The problem was discussed and also a solution was offered but we're not sure it will be included in DNN 9.2.2 (but rather in DNN 9.3.0).

In order to get things working for you we've prepared a standalone installable package that will get you a successful DNN 9.2.0, 9.2.1 or even 9.2.2 RC upgrade process.

All you need to do is to install the package here before starting the DNN Upgrade process.

We've also submitted the solution that should close issue #2121 and details can be found here. For all those of you that need a little more code to digest with this article then go ahead and continue reading...

 

Our devs debugged through the upgrade process of the Newtonsoft library and here are the findings:
The DNN manifest file has two components (in this order):
1. Assembly component 
2. Config component

The installer executes the Assembly component installer that copies the newtonsoft.json.dll version 10.0.3 in bin folder and then calls [`AddOrUpdateBindingRedirect()`](https://github.com/dnnsoftware/Dnn.Platform/blob/development/DNN%20Platform/Library/Services/Installer/Installers/AssemblyInstaller.cs#L194) which updates the `web.config` with the binding redirect to 10.0.3.
Then, the Config installer is executed which updates the `web.config` with the assembly binding once more.

The issue with DnnSharp's `<codebase>` assembly binding (and maybe other vendors) is in that second step of the install process. The [`path`](https://github.com/dnnsoftware/Dnn.Platform/blob/1829d1810e6ca6476302669060717c3c9b1f2d86/DNN%20Platform/Components/Newtonsoft/DotNetNuke.Newtonsoft.Json.dnn#L33) attribute set in the Newtonsoft package to update the binding redirect is not specific enough and doesn't take into consideration that there could be other `dependentAssembly` elements in `web.config` for newtonsoft. It targets the first `ab:dependentAssembly` element with `@name='Newtonsoft.Json'`.

In a clean DNN pre 9.2.0 the `<assemblyBinding>` element contains only one `dependentAssembly`:
``` XML
<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
```

When installing any DnnSharp module the `assemblyBinding` changes to:
``` XML
<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
...
<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
    <codeBase version="8.0.0.0" href="bin\NewtonSoft.Json-8.0.0.0\Newtonsoft.Json.dll" />
</dependentAssembly>
```

After the AssemblyInstaller is executed the `web.config` changes to (note the order of the elements):
``` XML
<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
    <codeBase version="8.0.0.0" href="bin\NewtonSoft.Json-8.0.0.0\Newtonsoft.Json.dll" />
</dependentAssembly>
...
<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
    <bindingRedirect oldVersion="0.0.0.0-32767.32767.32767.32767" newVersion="10.0.0.0" />
</dependentAssembly>
```

Now it is ConfigInstaller turn to update the `web.config`. It [searches](https://github.com/dnnsoftware/Dnn.Platform/blob/development/DNN%20Platform/Library/Services/Installer/XmlMerge.cs#L250) for the dependentAssembly with path `/configuration/runtime/ab:assemblyBinding/ab:dependentAssembly[ab:assemblyIdentity/@name='Newtonsoft.Json']` which matches the first one (DnnSharp's one). Then it [searches](https://github.com/dnnsoftware/Dnn.Platform/blob/development/DNN%20Platform/Library/Services/Installer/XmlMerge.cs#L531) for the target node with `/configuration/runtime/ab:assemblyBinding/ab:dependentAssembly[ab:assemblyIdentity/@name='Newtonsoft.Json']/ab:bindingRedirect` which matches the `bindingRedirect` of the second `dependentAssembly` (the one added earlier by AssemblyInstaller). Next it tries to [remove](https://github.com/dnnsoftware/Dnn.Platform/blob/development/DNN%20Platform/Library/Services/Installer/XmlMerge.cs#L561) the `bindingRedirect` of the second dependentAssembly from the first dependentAssembly. This throws a `System.ArgumentException` with message `The node to be removed is not a child of this node.`

### Solution

There are two solutions:
1. Strengthen the path's XPath like this: `/configuration/runtime/ab:assemblyBinding/ab:dependentAssembly[ab:assemblyIdentity/@name='Newtonsoft.Json' and ab:bindingRedirect]`. This will prevent mismatching rootNode / targetNode elements between codabase and bindingRedirect bindings. There could be other bindingRedirect bindings that could interfere with this.
2. Add an additional Config component before the existing one that removes all the bindingRedirects for older newtonsoft assemblies **but not the codabase bindings**. Then, the existing Config component will insert a bindingRedirect only if there is no bindingRedirect for version 10. There could be unforeseen issues with this approach.
Print
0 Comments
Rate this article:
No rating

Categories: General News, Free DNN Modules, Tip Of The WeekNumber of views: 404

Tags:

Mihai StanciuMihai Stanciu

Other posts by Mihai Stanciu

Contact author

Name:
Email:
Subject:
Message:
x

About Us

DNN Sharp is a leading provider with a proven track record in defining, designing and developing DNN Modules catering for a passionate community of thousands of users.

While our core focus is on DNN modules, our mission is to provide top quality products complemented by fast and reliable Customer support. We listen to our Customers and produce a variety of solutions to meet the complex needs of our global audience.







«November 2018»
MonTueWedThuFriSatSun
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789


Our latest news and gossips, must-reads, tutorials and how-tos, as well as other random awesomeness from across the DNN world...

Stay in the loop subscribing to our newsletter!