You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET 4.5含动态键JSON反序列化问题及转换器报错解决

VB.NET 4.5 动态键JSON反序列化问题解决

问题核心

你的JSON结构混合了固定字段(Errors二维数组、timestamp)和动态命名的Item元素(键名不固定但结构一致),标准类无法直接映射,自定义Converter实现不当导致System.InvalidCastException(无法将Func1[System.Object]转换为PrinterAudit.Rootobject`)。

正确实现步骤

1. 定义模型类

先明确Item和根对象的结构,用Dictionary存储动态Item:

Imports Newtonsoft.Json

' 单个Item的结构,根据实际JSON字段调整
Public Class AuditItem
    Public Property Id As Integer
    Public Property Status As String
    Public Property Details As String
    ' 其他Item固定字段...
End Class

' 根对象,包含动态Item字典、Errors和timestamp
Public Class AuditRoot
    Public Property Items As Dictionary(Of String, AuditItem)
    Public Property Errors As String(,)
    Public Property Timestamp As DateTime
End Class

2. 实现自定义JsonConverter

这个Converter会遍历根JSON对象,区分固定字段和动态Item:

Public Class AuditRootConverter
    Inherits JsonConverter(Of AuditRoot)

    Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As AuditRoot, hasExistingValue As Boolean, serializer As JsonSerializer) As AuditRoot
        Dim root As New AuditRoot()
        root.Items = New Dictionary(Of String, AuditItem)()

        ' 遍历JSON对象的所有属性
        While reader.Read() AndAlso reader.TokenType <> JsonToken.EndObject
            If reader.TokenType = JsonToken.PropertyName Then
                Dim propName = reader.Value.ToString().ToLower()
                reader.Read() ' 移动到属性值位置

                Select Case propName
                    Case "errors"
                        ' 反序列化二维数组
                        root.Errors = serializer.Deserialize(Of String(,))(reader)
                    Case "timestamp"
                        ' 反序列化时间戳
                        root.Timestamp = serializer.Deserialize(Of DateTime)(reader)
                    Case Else
                        ' 动态Item,反序列化为AuditItem并加入字典
                        Dim item = serializer.Deserialize(Of AuditItem)(reader)
                        root.Items.Add(reader.PreviousPath.Split(".").Last(), item)
                End Select
            End If
        End While

        Return root
    End Function

    ' 如果不需要序列化根对象,直接抛出异常即可
    Public Overrides Sub WriteJson(writer As JsonWriter, value As AuditRoot, serializer As JsonSerializer)
        Throw New NotImplementedException("序列化功能未实现")
    End Sub
End Class

3. 执行反序列化

在反序列化时指定自定义Converter:

' 示例JSON(替换为你的实际JSON)
Dim jsonContent As String = "{""Printer001"": {""Id"":1,""Status"":""Online"",""Details"":""正常""},""Printer002"": {""Id"":2,""Status"":""Offline"",""Details"":""卡纸""},""Errors"":[[""E001"",""连接失败""],[""E002"",""墨粉不足""]],""timestamp"":""2024-05-20T14:30:00""}"

Dim serializerSettings As New JsonSerializerSettings()
serializerSettings.Converters.Add(New AuditRootConverter())

Try
    Dim auditData = JsonConvert.DeserializeObject(Of AuditRoot)(jsonContent, serializerSettings)
    ' 成功获取数据,可使用auditData.Items、auditData.Errors等
Catch ex As InvalidCastException
    ' 排查Converter是否返回了正确的AuditRoot实例,或是否误用了非泛型Converter
    Console.WriteLine($"类型转换错误:{ex.Message}")
Catch ex As Exception
    Console.WriteLine($"反序列化失败:{ex.Message}")
End Try

错误原因分析

你遇到的InvalidCastException通常是以下情况导致:

  • 自定义Converter未继承泛型JsonConverter(Of AuditRoot),而是继承了非泛型JsonConverter,且ReadJson方法返回的对象类型与目标类型不匹配
  • ReadJson方法内部逻辑错误,返回了Func(Of Object)或其他非AuditRoot类型的对象
  • 反序列化时未正确配置Converter,导致框架尝试用默认逻辑解析,触发类型不匹配

内容的提问来源于stack exchange,提问作者NapkinBob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:31:03