Reputation: 114
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);
Upvotes: 0
Views: 5154
Reputation: 36645
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);
Upvotes: 1
Reputation: 1679
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; }
}
}
Upvotes: 2