JsonConvert.DeserializeObject 知道 class 名字(字符串)

JsonConvert.DeserializeObject knowing class name (string)

我有一个 vb.net class,其中包含一些可序列化的子 classes

Public Class Model
    <Serializable>
    Public class foo
        Public Property id as Integer
        Public Property name as String
    End Class

    <Serializable>
    Public Class bar
        Public Property grading as Integer
        Public Property minWage as Decimal
        Public Property maxWage as Decimal
    End Class
End Class

现在我从 Web 服务接收到一个对象(json 格式的字符串)及其 class 名称(字符串),我想将其反序列化为我的对象。

我可以做,因为它确实有效,

Imports Newtonsoft.Json
    
Public Shared Function Deserialize(ByVal Json As String, ByVal name As String) As Object
   
    Select Case name
        Case "foo"
            Return JsonConvert.DeserializeObject(of Model.foo)(Json)
        Case "bar"
            Return JsonConvert.DeserializeObject(of Model.bar)(Json)
    End Select
End Function

但是正如你想象的那样,我有很多 classes,而不仅仅是 2 个,所以我尝试使用 Reflection

Imports System.Reflection
Imports Newtonsoft.Json

Public Shared Function Deserialize(ByVal Json As String, ByVal name As String) As Object

    Dim assembly As Assembly = Assembly.GetAssembly(GetType(Model))
    Dim type As Type = assembly.[GetType]("Model." & name) ' Why is this always Nothing?
    Dim objInstance As Object = Activator.CreateInstance(type)
    '        objInstance = JsonConvert.DeserializeObject(Of ???)(Json)

    Return objInstance 
End Function

但一方面类型变量总是Nothing,另一方面,我不知道用什么代替注释。

能请教一下吗?

您需要在定义 Model class 的地方添加命名空间。
嵌套的 class 由 + 分隔,因此您必须将其添加到要创建的 Class 对象的全名中。

那么组成的字符串就是"[Namespace].[ClassName]+[NestedClassName]"

您不需要创建实例,Json 序列化程序会为您完成。将 class 的类型传递给接受类型作为第二个参数的 JsonConvert.DeserializeObject() 方法。

Public Shared Function Deserialize(Json As String, className As String) As Object
    Dim asm = Assembly.GetAssembly(GetType(Model))
    Dim t As Type = asm.GetType($"{asm.GetName().Name}.Model+{className}")
    Return JsonConvert.DeserializeObject(Json, t)
End Function

如何使用它,由您决定:)

更多通用:

Public Shared Function Deserialize(Of T)(Json As String, className As String) As Object
    Dim asm = Assembly.GetAssembly(GetType(T))
    Dim t1 As Type = asm.GetType($"{asm.GetName().Name}.{GetType(T).Name}+{className}")
    Return JsonConvert.DeserializeObject(Json, t1)
End Function

呼叫为:

Dim deserialized = Deserialize(Of Model)(Json, "foo")

我已经部分解决了我的问题,我现在可以像这样创建正确的对象

Dim objType As Type = (From asm In AppDomain.CurrentDomain.GetAssemblies() From type In asm.GetTypes() Where type.IsClass AndAlso type.Name = name Select type).Single()
Dim objInstance As Object = Activator.CreateInstance(objType)

这是我最终的工作函数,感谢 Jimi!

Public Shared Function Deserialize(ByVal Json As String, ByVal name As String) As Object
    Try
        Dim objType As Type = (From asm In AppDomain.CurrentDomain.GetAssemblies() From type In asm.GetTypes() Where type.IsClass AndAlso type.Name = name Select type).Single()

        Return JsonConvert.DeserializeObject(Json, objtype)

    Catch ex As Exception
        Throw New Exception("Unknown class")
    End Try
End Function