Mdumanoj
Mdumanoj

Reputation: 527

Deserialize timestamp value in JSON to DateTime while Model Binding

I'm developing a Web API using the ASP.NET Core 2 and I have a Model class as following.

public class Model
{
   int id { get; set; }
   DateTime date { get; set; }
}

I am using JSON in the Request Body. Request Json is like

{
  "id" : 1,
  "date" : 1525261719 
}

Binding this JSON data to the Model class like this in Controller

[HttpPost]
public async Task<IActionResult> PostEvent([FromBody] Model model)
{ 
    // Some code here
}

I was not able to parse Unix timestamp into the DateTime type. I saw some examples like JSON Converter, IModelBinder nothing helps. As I was new to .NET world I don't know how to proceed for this issue.

Any help is much appreciated.

Upvotes: 0

Views: 4366

Answers (2)

Mdumanoj
Mdumanoj

Reputation: 527

I found solution for this. I used ITypeConverter

// Converts timestamp to DateTime
public class DateTimeConverter : ITypeConverter<long?, DateTime?>
{
    private readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    public DateTime? Convert(long? source, DateTime? destination, ResolutionContext context)
    {
        if (!source.HasValue) return null;
        return _epoch.AddSeconds(source.Value);
    }
}

// Converts DateTime to Timestamp
public class TimeStampConverter : ITypeConverter<DateTime?, long?>
{
    private readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    public long? Convert(DateTime? source, long? destination, ResolutionContext context)
    {
        if (source == null) return null;
        var result = (long)(source - _epoch).Value.TotalSeconds;
        return result;
    }
}

And I created a Map like this in startup.cs

AutoMapper.Mapper.Initialize(x =>
            {
                x.CreateMap<long?, DateTime?>().ConvertUsing<DateTimeConverter>();
                x.CreateMap<DateTime?, long?>().ConvertUsing<TimeStampConverter>();
            });

I used this couple of classes in my project and it is working fine. This may help anyone who is trying to achieve the same thing.

Upvotes: 1

Pepito Fernandez
Pepito Fernandez

Reputation: 2440

I had the same issue. I wrote this JsonConverter. Keep in mind that this is tailor-made for my specific situation.

public class UnixEpochTimeToDateTimeConverter: JsonConverter
{
    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {

        if (reader.TokenType == JsonToken.Null) return null;
        if (reader.TokenType != JsonToken.Integer) return null;
        if (!reader.Path.Contains("time")) return null;

        return long.TryParse(reader.Value.ToString(), out var epoch)
            ? DateTimeOffset.FromUnixTimeMilliseconds(epoch).DateTime
            : DateTime.Now;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }
}

Upvotes: 2

Related Questions