7

I have an object which contains a property with JsonConverter attribute. For data read and write, converter not working. The declared property is

[JsonConverter(typeof(EpochDateTimeConverter))]
public DateTime CreatedOn { get; set; } 

The EpochDateTimeConverter is

public class EpochDateTimeConverter : DateTimeConverterBase
    {
        private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (value == null)
            {
                writer.WriteNull();
                return;
            }

            long millisecondsSinceEpoch;
            if (value is DateTime)
            {
                millisecondsSinceEpoch = Convert.ToInt64((((DateTime)value).ToUniversalTime() - epoch).TotalMilliseconds);
            }
            else
            {
                if (!(value is DateTimeOffset))
                    throw new JsonSerializationException("Expected date object value.");
                millisecondsSinceEpoch = Convert.ToInt64((((DateTimeOffset)value).ToUniversalTime().UtcDateTime - epoch).TotalMilliseconds);
            }
            writer.WriteValue(millisecondsSinceEpoch);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                if (objectType != typeof(DateTime?) && objectType != typeof(DateTimeOffset?))
                    throw new JsonSerializationException($"Cannot convert null value to {objectType}");

                return null;
            }
            if (reader.TokenType == JsonToken.Integer || reader.TokenType == JsonToken.Float)
            {
                var millisecondsSinceEpoch = (long)reader.Value;
                var dateTime = FromUnixTime(millisecondsSinceEpoch);
                if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
                {
                    return dateTime;
                }
                else
                {
                    return new DateTimeOffset(dateTime);
                }
            }
            if (reader.TokenType == JsonToken.Date || reader.TokenType == JsonToken.Float)
            {
                return ConvertToUnixTimestamp(Convert.ToDateTime(reader.Value));
            }
            throw new JsonSerializationException($"Cannot convert to DateTime or DateTimeOffset from token type {reader.TokenType}");
        }
        private static DateTime FromUnixTime(long unixTime)
        {
            try
            {
                return epoch.AddSeconds(unixTime);
            }
            catch(Exception)
            {
                unixTime = unixTime / 1000;
                return epoch.AddSeconds(unixTime);
            }

        }

        public static double ConvertToUnixTimestamp(DateTime date)
        {
            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            TimeSpan diff = date.ToUniversalTime() - origin;
            return Math.Floor(diff.TotalSeconds);
        }

    }

I can not get the error. But EpochDateTimeConverter not called automatically. I have not understood what's the wrong. Anyone can help me?

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Md. Abdul Alim
  • 707
  • 1
  • 6
  • 19

3 Answers3

6

Make sure to use System.Text.Json.Serialization not Newtonsoft.Json.

Twenty
  • 5,234
  • 4
  • 32
  • 67
Matt
  • 2,096
  • 14
  • 20
-2

This is calling automatically when your JsonConverter is progressing on that time. By default .NET Core API uses to serialize and deserialize the json object using Newtonsoft.Json. Here JsonConverter also exist in the Newtonsoft.Json namespace so in term of using this when you use this JsonConverter static class that time it will call automatically with proper procedure.

JsonConvert.SerializeObject(YourClassWhichContainThePropertyWithYourAttribute);

Also you can check this by calling this function

  • When JsonConverter using as property attribute the called automatically. JsonConvert.SerializeObject no need to use in this time. – Md. Abdul Alim Mar 13 '18 at 08:27
  • This property attribute is calling when this Object is Serialize or Deserialize So either without calling any kind of method this attribute does not work. – Ashiqur Rahman Emran Mar 13 '18 at 08:43
  • No, no. You did not get my point. EpochDateTimeConverter using for datetime conversion. Its not data serialize issue. Thanks. – Md. Abdul Alim Mar 13 '18 at 08:51
-3

After some research I found a mismatch between Enitity and Converter. The JsonConverter were not same of both class. That's why it was not called. After update JsonConverter its working.

Md. Abdul Alim
  • 707
  • 1
  • 6
  • 19
  • 15
    This answer isn't terribly helpful - what do you mean by "not of same class"? Please consider trying to make your answer helpful to anyone who runs into the same problem later, indicating exactly what you had to change. – Jon Skeet Sep 14 '18 at 14:15
  • Ok I will explain – Md. Abdul Alim Sep 15 '18 at 03:02
  • 7
    Is it possible to have that explanation, please? – HappyDump Jan 24 '20 at 13:44
  • @HappyDump Have any problem? Here, is object annotation mismatch problem – Md. Abdul Alim Jan 27 '20 at 05:51
  • Not sure what if this is what he meant but I had the same problem and found that my [JsonProperty("propname")] attribute was incorrect. I.e. it didn;t match the json I was trying to parse. E.g. it should have been [JsonProperty("prop_name")]. Hope this comment saves somebody some time. – mfa Oct 08 '20 at 04:03
  • 2
    in my case, the entity was using `JsonConverter` property from `System.Text.Json` and the converter was extending `JsonConverter` from `Newtonsoft.Json`. I think that is what he meant...using the same package for both classes, solved the issue for me. – Ramon Dias Dec 21 '20 at 19:15