.netasp.net-corenugetsage-erpaccpac

ACCPAC Missing Method Exception


I have a ASP.NET Core 1.1 webserver running on full .NET 4.6.2. I am using the ACCPAC.Advantage.dll's (packaged in a custom NuGet bundle) to connect to a local Sage installation. Previously connections were successfully initiated and I was able to post batches to Accounts Payable. But now initiating the connection fails with the following error:

System.MissingMethodException: Method not found: 'ACCPAC.Advantage.DBLink ACCPAC.Advantage.Session.OpenDBLink(ACCPAC.Advantage.DBLinkType, ACCPAC.Advantage.DBLinkFlags)'.

Intellisense and ReSharper's decompile functionality can easily find the Session.OpenDBLink method, so why is it missing during runtime?

Could it be pulling the wrong assembly from the Global Assembly Cache? What is the best way to resolve that without breaking other applications that require those assemblies?


Solution

  • Another Sage third-party developer brought up a .Net issue that sounds like what you're experiencing. This is what they had to say on the Sage City forums (Sage City Post):

    In Sage 2018 PU2 Sage have decided to....

    Bump the version number of \HKLM\SOFTWARE\WOW6432Node\ACCPAC International, Inc.\ACCPAC\Web\A4WNET to 6.5.0.2 but not keep this in step with the .net runtime library version (6.5.0.10). This has broken 8 versions of Sage300 where the two have been in step.

    Why is this a problem? The .net assemblies are loaded into the GAC and to avoid having to recompile/re-release your application after version update we use reflection to load the assemblies.

    Prior to this update we could use System.Reflection.Assembly.Load([full assembly signature]). However, to use this method we need to know the version of the S300 runtime assembly (Accpac.Advantage.dll), which we obtained by querying the registry.

    To work around the issue we now use the System.Reflection.Assembly.LoadFile method. This is fine, but it does bypass the checks the .net assembly loader does when calling Load.

    const string SAGE_RUNTIME = "Sage\\Sage 300 ERP\\ACCPAC.Advantage.dll";
    
    Assembly assem =
    Assembly.LoadFile(
    System.IO.Path.Combine(
    Environment.GetFolderPath(
    Environment.SpecialFolder.CommonProgramFilesX86), SAGE_RUNTIME));
    

    Edit: Another option would be to use the COMApi interface via .Net.