反序列化JSON缺少的属性时设置默认值

db2dz4w8  于 2023-08-08  发布在  其他
关注(0)|答案(1)|浏览(204)

我试图给我的类分配一个默认值,但我没有JSON中列出的属性。
这是我用来反序列化JSON的类

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

字符串
这是我正在尝试反序列化的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\u00e3o",
      "expediente_feriados": "0",
      "expediente_bloqueio_pc": 0,
      "expediente_bloqueio_tolerancia": "0"
    }],
     }
}


在这个场景中,我尝试做的是分配一个默认值,这样它就没有JSON中的属性,设置默认值,这样就可以测试它,只需删除JSON中标识的行
这是我用来读取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


我已经在SO上尝试了以下建议的解决方案:
Default value for missing properties with JSON.net
Why when I deserialize with JSON.NET ignores my default value?
但都没有成功。
我需要的是在缺少JSON属性时设置默认值,所以我请求大家帮助解决这个问题。

ttisahbt

ttisahbt1#

你这里有几个问题:

  1. JSON中没有属性"expediente_opcao_quinta"的值,因此Expediente.expediente_opcao_quintanull
    1.有几个字符串在JSON中的值显式为null,例如"result[0].expediente.expediente_opcao_sabado"的值。
    1.还缺少值默认为null的字符串值属性。
    解决这些问题的最简单方法是在构造属性时自动将属性初始化为非空值,如初始化自动实现的属性中所示,并将<JsonProperty(NullValueHandling := NullValueHandling.Ignore)>应用于任何不应为空的属性,以强制Json.NET在反序列化和序列化时忽略空值。
    因此,您的数据模型应该看起来像:
Public Class Expediente
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property expediente_opcao_domingo As ExpedienteOpcao = New ExpedienteOpcao()
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property expediente_opcao_segunda As ExpedienteOpcao = New ExpedienteOpcao()
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property expediente_opcao_terca As ExpedienteOpcao = New ExpedienteOpcao()
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property expediente_opcao_quarta As ExpedienteOpcao = New ExpedienteOpcao()
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property expediente_opcao_quinta As ExpedienteOpcao = New ExpedienteOpcao()
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property expediente_opcao_sexta As ExpedienteOpcao = New ExpedienteOpcao()
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property expediente_opcao_sabado As ExpedienteOpcao = New ExpedienteOpcao()

    Public Property expediente_feriados As String
    Public Property expediente_bloqueio_pc As String
    Public Property expediente_bloqueio_tolerancia As String
End Class

Public Class ExpedienteOpcao
    Public Property isDiaUtil As Integer
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    Public Property hora_inicial As String = ""
    <JsonProperty(NullValueHandling := NullValueHandling.Ignore)> _
    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

字符串
备注:

  • 你有一个7个相同的类,它们的名字像ExpedienteOpcaoDomingoExpedienteOpcaoQuarta,似乎对应于一周中的几天。我猜您是用某种代码生成工具创建这些类的。代码生成工具有时会无法检测和合并相同的类型,但由于在这种情况下,它们似乎应该是相同的,所以我在我的回答中将它们设置为相同的。
  • 在你的问题中,你捕捉并忽略所有的异常。这通常是一个坏主意,因为您会丢失有关问题原因的所有信息,并且您的代码可能会使用损坏的数据继续前进。例如,参见Is catching general exceptions really a bad thing?以获得一些额外的讨论。
  • 虽然您可以使用 Default value for missing properties with JSON.net 中的答案来使用DefaultValueAttribute为缺少原始值的属性提供默认值,但由于CLR中内置的属性参数类型的限制,您不能使用DefaultValueAttributeExpedienteOpcao等复杂属性值提供默认值。

演示小提琴here

相关问题