Imports System.Collections
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Reflection
Imports System.ComponentModel.DataAnnotations
Imports Newtonsoft.Json.Linq
Imports Newtonsoft.Json.Converters
Imports Newtonsoft.Json.Serialization
Public Interface ISerializationContext
Function TryGetNameTable(Of T)(ByRef table as INameTable(Of T)) as Boolean
Public Interface INameTable(Of T)
Function TryGetName(value As T, ByRef name as String) As Boolean
Function TryGetValue(name as String, ByRef value as T) As Boolean
Public Class NameTable(Of T) : Implements INameTable(Of T)
Public Property Dictionary as Dictionary(Of String, T) = New Dictionary(Of String, T)()
Public Property ReverseDictionary as Dictionary(Of T, String) = New Dictionary(Of T, String)()
Public Function Add(value as T, name as String) as T
Dictionary.Add(name, value)
ReverseDictionary.Add(value, name)
Public Function TryGetName(value As T, ByRef name as String) As Boolean Implements INameTable(Of T).TryGetName
Return ReverseDictionary.TryGetValue(value, name)
Function TryGetValue(name as String, ByRef value as T) As Boolean Implements INameTable(Of T).TryGetValue
Return Dictionary.TryGetValue(name, value)
Public Class ObjectToNameConverter(Of T)
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return GetType(T) = objectType
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
Dim tValue = CType(value, T)
Dim context as ISerializationContext = CType(serializer.Context.Context, ISerializationContext)
Throw New JsonSerializationException("No ISerializationContext.")
Dim nameTable as INameTable(Of T) = Nothing
If (Not context.TryGetNameTable(Of T)(nameTable))
Throw New JsonSerializationException("No NameTable.")
Dim name as String = Nothing
if (Not nameTable.TryGetName(tValue, name))
Throw New JsonSerializationException("No Name.")
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim context as ISerializationContext = CType(serializer.Context.Context, ISerializationContext)
Throw New JsonSerializationException("No ISerializationContext.")
Dim nameTable as INameTable(Of T) = Nothing
If (Not context.TryGetNameTable(Of T)(nameTable))
Throw New JsonSerializationException("No NameTable.")
Dim name As String = serializer.Deserialize(Of String)(reader)
dim tValue as T = Nothing
nameTable.TryGetValue(name, tValue)
<JsonConverter(GetType(ObjectToNameConverter(Of SomePropertyClass)))> _
Public Property SomeProperty As SomePropertyClass
Public Class SomePropertyClass
Public Class MySerializationContext : Implements ISerializationContext
Public Function Add(value as SomePropertyClass, name as String) as SomePropertyClass
Return SomePropertyNameTable.Add(value, name)
Property SomePropertyNameTable as NameTable(Of SomePropertyClass) = New NameTable(Of SomePropertyClass)
Public Function TryGetNameTable(Of T)(ByRef table as INameTable(Of T)) as Boolean Implements ISerializationContext.TryGetNameTable
if (GetType(T) Is GetType(SomePropertyClass))
table = SomePropertyNameTable
Dim context as MySerializationContext = New MySerializationContext()
Dim someProperty as SomePropertyClass = context.Add(New SomePropertyClass(), "My Name")
Dim root as RootObject = New RootObject With { .SomeProperty = someProperty }
Dim settings = new JsonSerializerSettings With _
.Context = New System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.All, context)
Dim json as String = JsonConvert.SerializeObject(root, settings)
dim root2 as RootObject = JsonConvert.DeserializeObject(Of RootObject)(json, settings)
Assert.IsTrue(root2.SomeProperty Is root.SomeProperty)
Assert.IsTrue(json.Equals("{""SomeProperty"":""My Name""}"))
Console.WriteLine("Environment version: " & Environment.Version.ToString())
Console.WriteLine("Json.NET version: " & GetType(JsonSerializer).Assembly.FullName)
Console.WriteLine("Unhandled exception: ")