1

Newtonsoft JSON pulled today from NuGet (V12 I think), .NET framework V4.7.2, simplified example of web service return. Code and output follows. All returned datetime forms are claimed to be UTC. Is there a deserialize setting option to treat no timezone info as UTC when deserialized into a datetimeoffset member of a class? Sample returned value is "2015-08-04T22:04:50"

If the datetimeoffset member is not marked as nullable, a parsable datetimeoffset without a timezone returns the default uninitialized value (1/1/0001 12:00:00 AM +00:00). In other words, deserialization is not successful. Same string when parsed with DateTimeOffset.Parse treats this as local timezone and returns a valid datetime in the local timezone. Not good, but can be handled in other code.

If the datetimeoffset member is marked as nullable, the member stays null (Nothing) which is also incorrect.

initialized value of datetimeoffset in class: 8/4/2015 10:04:50 PM +00:00

Newtonsoft.Json.JsonConvert.SerializeObject serialized string: {"dtoReturned":"2015-08-04T22:04:50+00:00"}

serialized string from web service: {"dtoReturned":"2015-08-04T22:04:50"}

deserialzied value of datetimeoffset: 8/4/2015 10:04:50 PM +00:00

uninitialized value of datetimeoffset in class: 1/1/0001 12:00:00 AM +00:00

deserialzied value of datetimeoffset: 1/1/0001 12:00:00 AM +00:00

initialized value of datetimeoffset in class: 8/4/2025 10:04:50 PM +00:00

Newtonsoft.Json.JsonConvert.SerializeObject serialized string: {"dtoReturned":"2025-08-04T22:04:50+00:00"}

serialized string from web service: {"dtoReturned":"2025-08-04T22:04:50"}

deserialzied value of datetimeoffset: 8/4/2025 10:04:50 PM +00:00

value of datetimeoffset in class before deserialize is nothing

deserialzied value of datetimeoffset in class is nothing

Imports System.IO Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    Dim obj1a As New TestClass1 ' transfers_v1_incoming
    obj1a.dtoReturned = DateTimeOffset.Parse("2015-08-04T22:04:50Z")
    Debug.Print("initialized value of datetimeoffset in class: " & obj1a.dtoReturned.ToString)
    Dim strIn As String = Newtonsoft.Json.JsonConvert.SerializeObject(obj1a)
    Debug.Print("Newtonsoft.Json.JsonConvert.SerializeObject serialized string: " & strIn)
    strIn = Replace(strIn, "+00:00", "")
    Debug.Print("serialized string from web service: " & strIn)

    Newtonsoft.Json.JsonConvert.DeserializeObject(strIn, obj1a.GetType)
    Debug.Print("deserialzied value of datetimeoffset: " & obj1a.dtoReturned.ToString)

    Dim obj1b As New TestClass1 ' transfers_v1_incoming
    Debug.Print("uninitialized value of datetimeoffset in class: " & obj1b.dtoReturned.ToString)

    Newtonsoft.Json.JsonConvert.DeserializeObject(strIn, obj1b.GetType)
    Debug.Print("deserialzied value of datetimeoffset: " & obj1b.dtoReturned.ToString)

    Dim obj2a As New TestClass2
    obj2a.dtoReturned = DateTimeOffset.Parse("2025-08-04T22:04:50Z")
    Debug.Print("initialized value of datetimeoffset in class: " & obj2a.dtoReturned.ToString)
    strIn = Newtonsoft.Json.JsonConvert.SerializeObject(obj2a)
    Debug.Print("Newtonsoft.Json.JsonConvert.SerializeObject serialized string: " & strIn)
    strIn = Replace(strIn, "+00:00", "")
    Debug.Print("serialized string from web service: " & strIn)
    Newtonsoft.Json.JsonConvert.DeserializeObject(strIn, obj2a.GetType)
    Debug.Print("deserialzied value of datetimeoffset: " & obj2a.dtoReturned.ToString)

    Dim obj2b As New TestClass2
    If IsNothing(obj2b.dtoReturned) Then
        Debug.Print("value of datetimeoffset in class before deserialize is nothing")
    Else
        Debug.Print("uninitialized value of datetimeoffset in class before deserialize: " & obj2b.dtoReturned.ToString)
    End If

    Newtonsoft.Json.JsonConvert.DeserializeObject(strIn, obj2b.GetType)
    If IsNothing(obj2b.dtoReturned) Then
        Debug.Print("deserialzied value of datetimeoffset in class is nothing")
    Else
        Debug.Print("deserialzied value of datetimeoffset: " & obj2b.dtoReturned.ToString)
    End If

End Sub

Class TestClass1
    Public Property dtoReturned As DateTimeOffset
End Class
Class TestClass2
    Public Property dtoReturned As DateTimeOffset?
End Class

End Class

1 Answers1

0

You are calling Newtonsoft.Json.JsonConvert.DeserializeObject(strIn, obj.GetType) as if it were going to mutate the obj variable. It will not.

Instead, you need to consume the object returned from this method. You will also need to cast it to your class.

obj = CType(Newtonsoft.Json.JsonConvert.DeserializeObject(strIn, obj.GetType), TestClass1)

Or easier, use the overload that takes the generic type definition:

obj = Newtonsoft.Json.JsonConvert.DeserializeObject(Of TestClass1)(strIn)
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575