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

VB.NET中JSON反序列化时为缺失属性设置默认值的问题

为VB类在JSON属性缺失时设置默认值

反序列化使用的VB类

Public Class cls_horarios
    Public Class Expediente
        Public Property expediente_opcao_domingo As ExpedienteOpcaoDomingo
        Public Property expediente_opcao_segunda As ExpedienteOpcaoSegunda
        Public Property expediente_opcao_terca As ExpedienteOpcaoTerca
        Public Property expediente_opcao_quarta As ExpedienteOpcaoQuarta
        Public Property expediente_opcao_quinta As ExpedienteOpcaoQuinta
        Public Property expediente_opcao_sexta As ExpedienteOpcaoSexta
        Public Property expediente_opcao_sabado As ExpedienteOpcaoSabado
        Public Property expediente_feriados As String
        Public Property expediente_bloqueio_pc As String
        Public Property expediente_bloqueio_tolerancia As String
    End Class

    Public Class ExpedienteOpcaoDomingo
        Public Property isDiaUtil As Integer
        Public Property hora_inicial As String
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoQuarta
        Public Property isDiaUtil As Integer
        Public Property hora_inicial As String
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoQuinta
        Public Property isDiaUtil As Integer
        Public Property hora_inicial As String
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoSegunda
        Public Property isDiaUtil As Integer
        Public Property hora_inicial As String
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoSexta
        Public Property isDiaUtil As Integer
        Public Property hora_inicial As String
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoTerca
        Public Property isDiaUtil As Integer
        Public Property hora_inicial As String
        Public Property hora_final As String
    End Class
   
    Public Class Result
        Public Property expediente As List(Of Expediente)
    End Class

    Public Class Root
        Public Property result As Result
    End Class
End Class

待反序列化的JSON

{
  "result": {
    "expediente": [{
      "expediente_opcao_domingo": {
        "isDiaUtil": 0,
        "hora_inicial": null,
        "hora_final": null
      },
      "expediente_opcao_segunda": {
        "isDiaUtil": 1,
        "hora_inicial": "09:00",
        "hora_final": "18:48"
      },
      "expediente_opcao_terca": {
        "isDiaUtil": 1,
        "hora_inicial": "09:00",
        "hora_final": "18:48"
      },
      "expediente_opcao_quarta": {
        "isDiaUtil": 1,
        "hora_inicial": "09:00",
        "hora_final": "18:48"
      },
      "expediente_opcao_sexta": {
        "isDiaUtil": 1,
        "hora_inicial": "09:00",
        "hora_final": "18:48"
      },
      "expediente_opcao_sabado": {
        "isDiaUtil": 0,
        "hora_inicial": null,
        "hora_final": null
      },
      "expediente_nome": "padrão",
      "expediente_feriados": "0",
      "expediente_bloqueio_pc": 0,
      "expediente_bloqueio_tolerancia": "0"
    }]
  }
}

读取JSON的代码

Public Sub PreencheConfiguracoesColaborador(ByVal dados As String)
    '//INICIO EXPEDIENTE DO COLABORADOR
    Dim horarioColab As cls_horarios.Root = JsonConvert.DeserializeObject(Of cls_horarios.Root)(dados)
    expediente_colab_quantidade = 0
    
    Try
        For Each item As Expediente In horarioColab.result.expediente
            expediente_colab_feriado = item.expediente_feriados
            expediente_colab_bloqueio_pc = item.expediente_bloqueio_pc
            expediente_colab_bloqueio_tolerancia = item.expediente_bloqueio_tolerancia

            expediente_colab_domingo = item.expediente_opcao_domingo.isDiaUtil
            expediente_colab_domingo_hora_entrada = FormatDateTime(item.expediente_opcao_domingo.hora_inicial.ToString, DateFormat.LongTime)
            expediente_colab_domingo_hora_saida = FormatDateTime(item.expediente_opcao_domingo.hora_final.ToString, DateFormat.LongTime)

            expediente_colab_segunda = item.expediente_opcao_segunda.isDiaUtil
            expediente_colab_segunda_hora_entrada = FormatDateTime(item.expediente_opcao_segunda.hora_inicial.ToString, DateFormat.LongTime)
            expediente_colab_segunda_hora_saida = FormatDateTime(item.expediente_opcao_segunda.hora_final.ToString, DateFormat.LongTime)

            expediente_colab_terca = item.expediente_opcao_terca.isDiaUtil
            expediente_colab_terca_hora_entrada = FormatDateTime(item.expediente_opcao_terca.hora_inicial.ToString, DateFormat.LongTime)
            expediente_colab_terca_hora_saida = FormatDateTime(item.expediente_opcao_terca.hora_final.ToString, DateFormat.LongTime)

            expediente_colab_quarta = item.expediente_opcao_quarta.isDiaUtil
            expediente_colab_quarta_hora_entrada = FormatDateTime(item.expediente_opcao_quarta.hora_inicial.ToString, DateFormat.LongTime)
            expediente_colab_quarta_hora_saida = FormatDateTime(item.expediente_opcao_quarta.hora_final.ToString, DateFormat.LongTime)

            expediente_colab_quinta = item.expediente_opcao_quinta.isDiaUtil
            expediente_colab_quinta_hora_entrada = FormatDateTime(item.expediente_opcao_quinta.hora_inicial.ToString, DateFormat.LongTime)
            expediente_colab_quinta_hora_saida = FormatDateTime(item.expediente_opcao_quinta.hora_final.ToString, DateFormat.LongTime)

            expediente_colab_sexta = item.expediente_opcao_sexta.isDiaUtil
            expediente_colab_sexta_hora_entrada = FormatDateTime(item.expediente_opcao_sexta.hora_inicial.ToString, DateFormat.LongTime)
            expediente_colab_sexta_hora_saida = FormatDateTime(item.expediente_opcao_sexta.hora_final.ToString, DateFormat.LongTime)

            expediente_colab_sabado = item.expediente_opcao_sabado.isDiaUtil
            expediente_colab_sabado_hora_entrada = FormatDateTime(item.expediente_opcao_sabado.hora_inicial.ToString, DateFormat.LongTime)
            expediente_colab_sabado_hora_saida = FormatDateTime(item.expediente_opcao_sabado.hora_final.ToString, DateFormat.LongTime)

            'expediente_colab_expediente_nome = item.expediente_nome
            expediente_colab_quantidade += 1
            Console.WriteLine("Feriado: " & expediente_colab_feriado & " Bloqueio Pc: " & expediente_colab_bloqueio_pc & " Bloqueio Tolerancia: " & expediente_colab_bloqueio_tolerancia & " Expediente Nome: " & expediente_colab_expediente_nome)
        Next
    Catch ex As Exception
        writeExeption(ex, False)
        Console.WriteLine("Erro Expediente: " & ex.Message)
    End Try
End Sub

问题描述

需要在JSON中缺失类属性时,自动为对应的类属性设置默认值(可通过移除JSON中的属性进行测试)。此前尝试过相关解决方案但未成功,现需解决该问题。


解决方案

方法1:使用[DefaultValue]属性+Json.NET配置

给类属性添加[DefaultValue]特性,并在反序列化时启用DefaultValueHandling.Populate配置,JSON缺失属性时会自动填充默认值。

修改后的类示例:

Imports System.ComponentModel
Imports Newtonsoft.Json

Public Class cls_horarios
    Public Class Expediente
        ' 初始化嵌套对象避免空引用
        Public Sub New()
            expediente_opcao_domingo = New ExpedienteOpcaoDomingo()
            expediente_opcao_segunda = New ExpedienteOpcaoSegunda()
            expediente_opcao_terca = New ExpedienteOpcaoTerca()
            expediente_opcao_quarta = New ExpedienteOpcaoQuarta()
            expediente_opcao_quinta = New ExpedienteOpcaoQuinta()
            expediente_opcao_sexta = New ExpedienteOpcaoSexta()
            expediente_opcao_sabado = New ExpedienteOpcaoSabado()
        End Sub

        Public Property expediente_opcao_domingo As ExpedienteOpcaoDomingo
        Public Property expediente_opcao_segunda As ExpedienteOpcaoSegunda
        Public Property expediente_opcao_terca As ExpedienteOpcaoTerca
        Public Property expediente_opcao_quarta As ExpedienteOpcaoQuarta
        Public Property expediente_opcao_quinta As ExpedienteOpcaoQuinta
        Public Property expediente_opcao_sexta As ExpedienteOpcaoSexta
        Public Property expediente_opcao_sabado As ExpedienteOpcaoSabado

        <DefaultValue("0")>
        Public Property expediente_feriados As String
        <DefaultValue("0")>
        Public Property expediente_bloqueio_pc As String
        <DefaultValue("0")>
        Public Property expediente_bloqueio_tolerancia As String
    End Class

    Public Class ExpedienteOpcaoDomingo
        <DefaultValue(0)>
        Public Property isDiaUtil As Integer
        <DefaultValue("00:00")>
        Public Property hora_inicial As String
        <DefaultValue("00:00")>
        Public Property hora_final As String
    End Class

    ' 其余ExpedienteOpcaoXX类按相同方式添加DefaultValue属性
    Public Class ExpedienteOpcaoQuarta
        <DefaultValue(0)>
        Public Property isDiaUtil As Integer
        <DefaultValue("00:00")>
        Public Property hora_inicial As String
        <DefaultValue("00:00")>
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoQuinta
        <DefaultValue(0)>
        Public Property isDiaUtil As Integer
        <DefaultValue("00:00")>
        Public Property hora_inicial As String
        <DefaultValue("00:00")>
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoSegunda
        <DefaultValue(0)>
        Public Property isDiaUtil As Integer
        <DefaultValue("00:00")>
        Public Property hora_inicial As String
        <DefaultValue("00:00")>
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoSexta
        <DefaultValue(0)>
        Public Property isDiaUtil As Integer
        <DefaultValue("00:00")>
        Public Property hora_inicial As String
        <DefaultValue("00:00")>
        Public Property hora_final As String
    End Class

    Public Class ExpedienteOpcaoTerca
        <DefaultValue(0)>
        Public Property isDiaUtil As Integer
        <DefaultValue("00:00")>
        Public Property hora_inicial As String
        <DefaultValue("00:00")>
        Public Property hora_final As String
    End Class
   
    Public Class Result
        Public Sub New()
            expediente = New List(Of Expediente)()
        End Sub
        Public Property expediente As List(Of Expediente)
    End Class

    Public Class Root
        Public Sub New()
            result = New Result()
        End Sub
        Public Property result As Result
    End Class
End Class

修改反序列化代码,添加配置:

Dim settings As New JsonSerializerSettings()
settings.DefaultValueHandling = DefaultValueHandling.Populate
' 若JSON中属性为null,忽略以保留默认值
settings.NullValueHandling = NullValueHandling.Ignore
Dim horarioColab As cls_horarios.Root = JsonConvert.DeserializeObject(Of cls_horarios.Root)(dados, settings)

方法2:在类构造函数中初始化默认值

无需特性,直接在构造函数中为属性设置默认值,Json.NET反序列化时会保留未被JSON覆盖的默认值:

Public Class ExpedienteOpcaoDomingo
    Public Sub New()
        isDiaUtil = 0
        hora_inicial = "00:00"
        hora_final = "00:00"
    End Sub
    Public Property isDiaUtil As Integer
    Public Property hora_inicial As String
    Public Property hora_final As String
End Class

Public Class Expediente
    Public Sub New()
        expediente_opcao_domingo = New ExpedienteOpcaoDomingo()
        expediente_opcao_segunda = New ExpedienteOpcaoSegunda()
        ' 其余嵌套对象同理初始化
        expediente_feriados = "0"
        expediente_bloqueio_pc = "0"
        expediente_bloqueio_tolerancia = "0"
    End Sub
    ' 属性声明保持不变
End Class

关键注意点

  • 嵌套对象(如Expediente中的expediente_opcao_domingo)必须在构造函数中实例化默认对象,否则JSON缺失该属性时会触发NullReferenceException。
  • 若JSON中存在null值,需启用NullValueHandling.Ignore避免覆盖已设置的默认值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:15:53