In my previous post I showed you how to get an object from a call to a SignalR method.

That call on the client side returns a Json.Net JObject. This is dynamic object.

However, the implementation of this object is not very VB.Net friendly.

If you try this.

vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports Microsoft.AspNet.SignalR.Client.Hubs
 
Module Module1
 
    Sub Main()
        Dim connection = New HubConnection("http://localhost:50865")
 
        Dim plants = connection.CreateHubProxy("Plants")
 
        plants.On(Of String)("addMessage", Sub(data) Console.WriteLine(data.ToString()))
 
        connection.Start().Wait()
 
        Dim line As String = Nothing
        Console.WriteLine("type the id + enter to send, type exit + enter to exit.")
        While line <> "exit"
            line = Console.ReadLine()
            plants.Invoke(Of Object)("GetPlant", line).ContinueWith(Sub(data)
                                                                        If data.Result IsNot Nothing Then
                                                                            Console.WriteLine(data.Result.ToString)
                                                                            Dim result = data.Result
                                                                            Console.WriteLine(result.Id)
                                                                            Console.WriteLine(result.Genus)
                                                                            Console.WriteLine(result.Species)
                                                                            For Each commonName In result.CommonNames
                                                                                Console.WriteLine(commonName)
                                                                            Next
                                                                        Else
                                                                            Console.WriteLine("No plant with that id.")
                                                                        End If
                                                                    End Sub)
        End While
    End Sub
 
End Module
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports Microsoft.AspNet.SignalR.Client.Hubs

Module Module1

    Sub Main()
        Dim connection = New HubConnection("http://localhost:50865")

        Dim plants = connection.CreateHubProxy("Plants")

        plants.On(Of String)("addMessage", Sub(data) Console.WriteLine(data.ToString()))

        connection.Start().Wait()

        Dim line As String = Nothing
        Console.WriteLine("type the id + enter to send, type exit + enter to exit.")
        While line <> "exit"
            line = Console.ReadLine()
            plants.Invoke(Of Object)("GetPlant", line).ContinueWith(Sub(data)
                                                                        If data.Result IsNot Nothing Then
                                                                            Console.WriteLine(data.Result.ToString)
                                                                            Dim result = data.Result
                                                                            Console.WriteLine(result.Id)
                                                                            Console.WriteLine(result.Genus)
                                                                            Console.WriteLine(result.Species)
                                                                            For Each commonName In result.CommonNames
                                                                                Console.WriteLine(commonName)
                                                                            Next
                                                                        Else
                                                                            Console.WriteLine("No plant with that id.")
                                                                        End If
                                                                    End Sub)
        End While
    End Sub

End Module

You will get an exception on result.Id

System.MissingMemberException was unhandled by user code
HResult=-2146233070
Message=Public member ‘Id’ on type ‘JObject’ not found.
Source=Microsoft.VisualBasic
StackTrace:
at Microsoft.VisualBasic.CompilerServices.Symbols.Container.GetMembers(String& MemberName, Boolean ReportErrors)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.FallbackGet(Object Instance, String MemberName, Object[] Arguments, String[] ArgumentNames)
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at Invoker(CallSiteBinder , Object , Object[] )
at Microsoft.VisualBasic.CompilerServices.IDOUtils.CreateRefCallSiteAndInvoke(CallSiteBinder Action, Object Instance, Object[] Arguments)
at Microsoft.VisualBasic.CompilerServices.IDOBinder.IDOGet(IDynamicMetaObjectProvider Instance, String MemberName, Object[] Arguments, String[] ArgumentNames, Boolean[] CopyBack)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
at SignalRConsole.Module1._Lambda$__2(Task`1 data) in E:UserschristiaanDocumentsVisual Studio 2012ProjectsSignalRTestingSignalRConsoleModule1.vb:line 25
at System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
InnerException:

The problem is the LateGet. But you can found out all about why this is a problem for VB.Net in the following post by Matthew Doig.

And none of the Json.net converters can solve this for us.

But we can use another library that does work with VB.Net.

And it’s called JSonFX. Just add it to your project via Nuget and then we can change our code to this.

vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports Microsoft.AspNet.SignalR.Client.Hubs
 
Module Module1
 
    Sub Main()
        Dim connection = New HubConnection("http://localhost:50865")
 
        Dim plants = connection.CreateHubProxy("Plants")
 
        plants.On(Of String)("addMessage", Sub(data) Console.WriteLine(data.ToString()))
 
        connection.Start().Wait()
 
        Dim line As String = Nothing
        Console.WriteLine("type the id + enter to send, type exit + enter to exit.")
        While line <> "exit"
            line = Console.ReadLine()
            plants.Invoke(Of Object)("GetPlant", line).ContinueWith(Sub(data)
                                                                        If data.Result IsNot Nothing Then
                                                                            Console.WriteLine(data.Result.ToString)
                                                                            Dim reader = New JsonFx.Json.JsonReader()
                                                                            Dim result = reader.Read(data.Result.ToString)
                                                                            Console.WriteLine(result.Id)
                                                                            Console.WriteLine(result.Genus)
                                                                            Console.WriteLine(result.Species)
                                                                            For Each commonName In result.CommonNames
                                                                                Console.WriteLine(commonName)
                                                                            Next
                                                                        Else
                                                                            Console.WriteLine("No plant with that id.")
                                                                        End If
                                                                    End Sub)
        End While
    End Sub
 
End Module
Imports System.Runtime.CompilerServices
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports Microsoft.AspNet.SignalR.Client.Hubs

Module Module1

    Sub Main()
        Dim connection = New HubConnection("http://localhost:50865")

        Dim plants = connection.CreateHubProxy("Plants")

        plants.On(Of String)("addMessage", Sub(data) Console.WriteLine(data.ToString()))

        connection.Start().Wait()

        Dim line As String = Nothing
        Console.WriteLine("type the id + enter to send, type exit + enter to exit.")
        While line <> "exit"
            line = Console.ReadLine()
            plants.Invoke(Of Object)("GetPlant", line).ContinueWith(Sub(data)
                                                                        If data.Result IsNot Nothing Then
                                                                            Console.WriteLine(data.Result.ToString)
                                                                            Dim reader = New JsonFx.Json.JsonReader()
                                                                            Dim result = reader.Read(data.Result.ToString)
                                                                            Console.WriteLine(result.Id)
                                                                            Console.WriteLine(result.Genus)
                                                                            Console.WriteLine(result.Species)
                                                                            For Each commonName In result.CommonNames
                                                                                Console.WriteLine(commonName)
                                                                            Next
                                                                        Else
                                                                            Console.WriteLine("No plant with that id.")
                                                                        End If
                                                                    End Sub)
        End While
    End Sub

End Module

Now our result will be.

type the id + enter to send, type exit + enter to exit.
1
{
“Id”: 1,
“Genus”: “Fagus”,
“Species”: “Sylvatica”,
“CommonNames”: [
"Common Beech"
]
}
Someone requested id: 1
1
Fagus
Sylvatica
Common Beech

Which is ultra cool.