Controlling the JSON.NET Version used

The full West Wind wwDotnetBridge includes support for JSON parsing and as such includes a reference to the popular JSON.NET library. This library is widely used and very reliable in parsing JSON into .NET objects. The wwJsonSerializer class uses this library to parse objects to .NET objects and then into FoxPro objects for an efficient and reliable way to provide a JSON parser. The wwDotnetBridge.ToJson() which can be used to create JSON from .NET objects also uses JSON.NET for serialization.

As cool as JSON.NET usage in West Wind products is, there are also some issues.

Because JSON.NET is so widely used in .NET, it's quite likely that you will run into other .NET components that also use JSON.NET - and quite likely use a different version of it. Since .NET can only load one version of a library at a time, this can cause a problem as one component will not be able to load the version of JSON.NET that it's binding to.

.NET is a statically linked runtime environment so binaries are almost always tied to a specific version number of the component. So if you have two components or an application and components trying to use different versions of the same library there can be a conflict.

Luckily .NET provides a workaround for this in most situations.

Assembly Redirects to the Rescue

.NET has a built-in system for runtime version forwarding which can be accomplished by way of Assembly Redirects the applications .config file.

For FoxPro application's this means you can put these assembly redirects into one of these files:

  • YourApp.exe.config
  • VFP9.exe.config

The config file is associated with the launching .EXE file, so that's either your standalone compiled application file, or the FoxPro IDE vfp9.exe.

The following is an example of .config file that forces JSON.NET usage of any version to version 8.0:

<?xml version="1.0"?>
<configuration>
  <startup>   
	<!-- <supportedruntime version="v4.0.30319"/> -->
	<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
	<!-- supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" -->    
    <!-- supportedRuntime version="v2.0.50727"/ -->    
  </startup>
  <runtime>
      <loadFromRemoteSources enabled="true"/>
  </runtime>
  
  <runtime>    
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="8.0.0.0" />
      </dependentAssembly>
	</assemblyBinding>      
  </runtime>
</configuration>

The key element is the <dependentAssembly> which describes Newtonsoft.Json and basically redirects any version found - oldVersion - to the newVersion. The new version in this case is the greater version number between the one wwDotnetBridge provides (6.x which is fairly old) and whatever other higher version is in use. You can check the .dll version number in the File details (Explorer -> Right Click DLL -> Details). In the example, here I'm interfacing with a .NET Socket.IO client library that uses Newtonsoft.Json version 8 and that's what's reflected in the newVersion. Now when wwDotnetBridge asks to version 6.0 of JSON.NET, .NET redirects to version 8.0 and everything works as long as the interface of the library supports the same signatures of methods and properties that the code accesses.

This approach works for any .NET assembly (dll) where there might be multiple versions in place.


© West Wind Technologies, 2023 • Updated: 09/18/18
Comment or report problem with topic