Search code examples
arraysjsonvb.netdeserializationmalformed

Deserialize malformed Json returning empty arrays


Please, I use VB.NET Http Requests to read data from a webservice. It used to send data this way:

[
    {
      "id": 7532,
      "nome": "LABOR INC.",
      "isClient": false,
      "personality": {
        "id": 2,
        "value": "CORPORATION"
      },
      "registryNumbers": [
        {
          "id": 9378,
          "number": "20786790174"
        }
      ],
      "personality_id": 2
    },
    {
      "id": 7537,
      "nome": "JOSE SILVA",
      "isClient": false,
      "personality": {
        "id": 1,
        "value": "PERSON"
      },
      "gender": {
        "id": 1,
        "value": "MALE"
      },
      "cityOfBirth": {
        "id": 355030,
        "value": "SAO PAULO"
      },
      "nationality": {
        "id": 85,
        "value": "BRAZILIAN"
      },
      "registryNumbers": [
        {
          "id": 9383,
          "number": "03217495388"
        }
      ],
      "personality_id": 1
    }
]

It was ok because unused fields (as "gender" and "cityOfBirth" for corporations) were omitted. Since some days, however, it started to send back these fields as empty arrays ([]), like this:

{
  "id": 7532,
  "nome": "LABOR INC.",
  "isClient": false,
  "personality": {
    "id": 2,
    "value": "CORPORATION"
  },
  "gender": [],
  "cityOfBirth": [],
  "nationality": [],
  "registryNumbers": [
    {
      "id": 9378,
      "number": "20786790174"
    }
  ],
  "personality_id": 2
}

And because of that it misfit the destiny properties in deserialization class, because these are not (and can't be) enumerations/arrays but single objects.

My question: is there some deserialization extension or attribute I can add to my classes in order to deserialize those ([]) as null/Nothing? Special thanks if it comes in VB.NET, but I'm able to read and adapt C# as well.

That is, I'd like to know how I could make my code halt when an array is "forced" into a property that expects single objects, and do the proper treatment at this point.


Solution

  • Tried and solved the problem with a custom converter:

    Public Class BogusArrayJsonConverter
        Inherits JsonConverter
        Public Overrides Function CanConvert(objectType As Type) As Boolean
            Return GetType(MyRecord).IsAssignableFrom(objectType)
        End Function
        Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
            If reader.TokenType = JsonToken.StartArray Then
                Return serializer.Deserialize(Of MyRecord())(reader).SingleOrDefault
            Else
                Return serializer.Deserialize(Of MyRecord)(reader)
            End If
        End Function
        Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
            Throw New NotImplementedException()
        End Sub
    End Class
    

    Thanks to all who tried to help me.