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
相关产品推荐
相关产品推荐

