Creating a signalR HubConnection client with Powershell

I'm trying to connect to a SignalR hub using a powershell script. I'm very new to powershell, so please excuse any rookie mistake.

I've set up a minimal not working example of what I've tried here: Gist

Relevant code:

Dlls download

$dllFolder = -join((Get-Item -Path ".\" -Verbose).FullName, "\bin\Debug\")
[string[]] $dllPathsToLoad = @("\Newtonsoft.Json.dll", "\Microsoft.AspNet.SignalR.Client.dll")
$token = "insertyourtokenhere"

function LoadDllPaths($dlls)
{
    foreach ($dll in $dlls)
    {
        $dllpath = $dllFolder + $dll
        [System.Reflection.Assembly]::LoadFrom($dllpath)
    }
}
[...]
LoadDllPaths($dllPathsToLoad)

      

Create HubConnection:

$server = "https://localhost/rest/"
[...]
$hub = New-Object Microsoft.AspNet.SignalR.Client.HubConnection($server)

      

Steps:

  • Create a new Visual Studio project
  • Add Newtonsoft.Json v10.0.2 Nuget Package (latest)
  • Add Microsoft.AspNet.SignalR.Client v2.2.2 Nuget Package (Latest)
  • Add powershell script to project root
  • With powershell (run as admin) enter .\HubConnectionTestsScript.ps1

Result:

outputView on imgur

Error : System.Management.Automation.MethodInvocationException: Exception calling ".ctor" with "1" argument(s): "Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified." ---> System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.
   at Microsoft.AspNet.SignalR.Client.Connection..ctor(String url, String queryString)
   at Microsoft.AspNet.SignalR.Client.HubConnection..ctor(String url, Boolean useDefaultUrl)
   --- End of inner exception stack trace ---
   at System.Management.Automation.DotNetAdapter.AuxiliaryConstructorInvoke(MethodInformation methodInformation, Object[] arguments, Object[] originalArguments)
   at System.Management.Automation.DotNetAdapter.ConstructorInvokeDotNet(Type type, ConstructorInfo[] constructors, Object[] arguments)
   at Microsoft.PowerShell.Commands.NewObjectCommand.CallConstructor(Type type, ConstructorInfo[] constructors, Object[] args)

      

This signalR source code object seems to be the problem, I just can't see how much of it might be causing this error.

Question:

Why does this error mention Newtonsoft.Json v6.0.0 when signalR relations say >=6.0.4

and I have 10.0.2

?

I am doing something wrong in my Powershell script, which could be causing this?

Many thanks! Any help is appreciated at this point

+3


source to share


1 answer


I was able to resolve this issue with some help from a colleague. Share the solution here in case anyone else is struggling with the same issue.

It looks like one of the SignalR dependencies is trying to load an old version of Newtonsoft.Json. We can make it redirect it to our own Newtonsoft.Json instance

Inspired by this gist , here's the idea:

When you load your Json assembly, store it in a variable

$newtonsoftAssembly = [System.Reflection.Assembly]::LoadFrom($dllFolder + "\Newtonsoft.Json.dll")

      



Then set up the redirect bindings. My best guess is that this intercepts any call to load the assembly, which gives us the ability to return our own Json assembly instead of letting it not find the version it needs (6.0.0 in my case).

function RedirectJsonBindings()
{
    $onAssemblyResolveEventHandler = [System.ResolveEventHandler] {
        param($sender, $e)
        # You can make this condition more or less version specific as suits your requirements
        if ($e.Name.StartsWith("Newtonsoft.Json")) {
            Write-Host "Newtonsoft assembly" $e.Name -ForegroundColor DarkGreen
            return $newtonsoftAssembly
        }
        foreach($assembly in [System.AppDomain]::CurrentDomain.GetAssemblies()) {
            if ($assembly.FullName -eq $e.Name) {
                return $assembly
            }
        }
        return $null
    }
    [System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolveEventHandler)

}

      

Finally, at the end of your script, unbind

# Detach the event handler (not detaching can lead to Qaru issues when closing PS)
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($onAssemblyResolveEventHandler)

      

+1


source







All Articles