skip to Main Content

I am using the Facebook Graph API which is returning a a json object that contains a datetime in a string in the following format: “created_time”: “2013-01-25T00:11:02+0000”

The deserialized object contains this datetime: “0001-01-01 00:00:00”, which I suppose is the equivalent of null. How can I deserialize the datetime string properly?

Here is my DTO class:

using System;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using Newtonsoft.Json.Converters;
using project.DTOs;

namespace project.DTOs.Facebook
{
    public class FacebookCommentResponseDto
    {
        [JsonPropertyName("id")]
        public string Id { get; set; }
        [JsonPropertyName("from")]
        public FacebookUserDto From { get; set; }
        [JsonPropertyName("message")]
        public string Message { get; set; }
        [JsonPropertyName("created_time")]
        [JsonConverter(typeof(CustomDateTimeConverter))]
        public DateTime CreatedTime { get; set;}
    }
    internal class CustomDateTimeConverter : IsoDateTimeConverter
    {
        public CustomDateTimeConverter()
        {
            base.DateTimeFormat = "yyyy-MM-ddTH:mm:ss.fffK";
        }
    }
}

This is the code where I deserialize the object:

var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(result);

2

Answers


  1. In your code you have using Newtonsoft.Json.Converters; and using System.Text.Json.Serialization;. On FacebookCommentResponseDto you use JsonPropertyName which belongs to System.Text but the converter class CustomDateTimeConverter is meant to be used with the Newtonsoft.Json attribute JsonProperty not with the System.Text attribute JsonPropertyName. Hence in your code the converter is never called.

    One solution ist to remove using System.Text.Json.Serialization; and replace JsonPropertyName in FacebookCommentResponseDto with JsonProperty. That means you only use Newtonsoft.Json and then the date conversion even works out-of-the-box without a converter. The following test is green:

    using Newtonsoft.Json;
    using System;
    using Xunit;
    
    namespace XUnitTestProject1
    {
        public class TimeFormatUnitTest
        {
            [Fact]
            public void ParseCreatedTime()
            {
                var timeString = "2013-01-25T00:11:02+0000";
                var json = "{ "created_time": "" + timeString + "" }";
    
                var data = JsonConvert.DeserializeObject<FacebookCommentResponseDto>(json);
    
                Assert.Equal(DateTime.Parse(timeString), data.CreatedTime);
            }
        }
    
        public class FacebookCommentResponseDto
        {
            [JsonProperty("created_time")]
            public DateTime CreatedTime { get; set; }
        }
    }
    
    Login or Signup to reply.
  2. As Marius said,your converter is for Newtonsoft while attributes are for System.Text.Json.You could change [JsonPropertyName] to [JsonProperty].

    Another solution is to custom converter which implements JsonConverter<DateTime> in System.Text.Json:

    1.Converter:

    public class FacebookCommentResponseDto
    {
        [JsonPropertyName("id")]
        public string Id { get; set; }
    
        [JsonPropertyName("message")]
        public string Message { get; set; }
        [JsonPropertyName("created_time")]
        [JsonConverter(typeof(CustomDateTimeConverter))]
        public DateTime CreatedTime { get; set; }
    }
    public class CustomDateTimeConverter : JsonConverter<DateTime>
    {
        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            Debug.Assert(typeToConvert == typeof(DateTime));
            return DateTime.Parse(reader.GetString());
        }
    
        public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString());
        }
    }
    

    2.Deserialize:

    var time = "2013-01-25T00:11:02+0000";
    var ID = "1001";                    
    var result = "{ "created_time": "" + time + "", "id": "" + ID + "" }";
    var data = System.Text.Json.JsonSerializer.Deserialize<FacebookCommentResponseDto>(result);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search