1

I'm trying to deserialize the following JSON:

{
    "Anriss": "SomeAnriss",
    "ArtikelId": 123123,
    "Image": null,
    "KanalId": 101,
    "MediumName": "SomeMediumName",
    "PublikationsDatum": "/Date(1573581177000)/",
    "Titel": "SomeTitel",
    "Link": null
}

via this method call:

await this.jsonHelper.DeserializeJsonContent<AvenueArtikelDetail>(httpResponseMessage.Content);

Method:

public async Task<T> DeserializeJsonContent<T>(HttpContent responseContent)
{
    var content = await responseContent.ReadAsStringAsync();
    var deserializedJsonContent = JsonSerializer.Deserialize<T>(content, new JsonSerializerOptions {PropertyNameCaseInsensitive = true, IgnoreNullValues = true});
    return deserializedJsonContent;
}

Unfortunately, I get the following error:

System.Text.Json.JsonException: 'The JSON value could not be converted to System.DateTime. Path: $.PublikationsDatum | LineNumber: 0 | BytePositionInLine: 353.'

The JSON comes from a call to this API method:

[HttpGet]
[AllowAnonymous]
public async Task<JsonResult> GetArtikelDetail(ArtikelDetailSearchDto searchDto)
{
    var artikelDetail = this.artikelDetailService.GetArtikelDetailBy(searchDto);
    return this.Json(artikelDetail, JsonRequestBehavior.AllowGet);
}

The publikationsDatum is a normal DateTime property

public DateTime PublikationsDatum { get; set; }

What am I doing wrong? How can I deserialize the publikationsDatum of the JSON back to a DateTime?

Thanks in advance

Edit: We're not using any JSON library and would like to keep it that way. We're using System.Text.Json

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
xeraphim
  • 4,375
  • 9
  • 54
  • 102
  • 3
    Does this answer your question? [Use JSON.NET to parse json date of format Date(epochTime-offset)](https://stackoverflow.com/questions/33224540/use-json-net-to-parse-json-date-of-format-dateepochtime-offset) – xdtTransform Nov 22 '19 at 13:51
  • It should work Json.net already handle this. Here is a live demo with nothing special other than copy-past involved. https://dotnetfiddle.net/PWXyix – xdtTransform Nov 22 '19 at 13:59
  • We're not using any JSON library. We use the built in `System.Text.Json`. Can I get it to work with this one? – xeraphim Nov 22 '19 at 14:14
  • Outch. Deserialize in a string and have an other property that parse the string. the ugly , but that the most simple way around it. – xdtTransform Nov 22 '19 at 14:23
  • As far as I can google `System.Text.Json` doesn't support the epoch format for dates. Instead it supports `ISO 8601-1:2019` date formats. Do you have control of the JSON source? – Palle Due Nov 22 '19 at 14:25
  • You may want to check out [Formatting DateTime in ASP.NET Core 3.0 using System.Text.Json](https://stackoverflow.com/q/58102189/215552) – Heretic Monkey Nov 22 '19 at 14:28
  • Is the API that is returning that JSON also in .NET Core 3? You should be able to change the way dates are serialized so that it doesn't use the ugly `/Date()/` syntax... – Heretic Monkey Nov 22 '19 at 14:30
  • @PalleDue yes we do have control of the JSON source. How can I specify the ISO format? – xeraphim Nov 22 '19 at 14:31
  • @HereticMonkey the other api unfortunately is not in .net core 3 :-( – xeraphim Nov 22 '19 at 14:31
  • 1
    In any case, you should be able to specify the date format: (If they're using Json.NET: [Specifying a custom DateTime format when serializing with Json.Net](https://stackoverflow.com/q/18635599/215552). If not: [ASP MVC 4 JsonResult how to use ISO 8601 dates?](https://stackoverflow.com/q/12506828/215552) – Heretic Monkey Nov 22 '19 at 14:35
  • The other API (source of the JSON) is a asp.net mvc application that uses the controller method `this.Json(dto);` to serialize it... so no JSON.net – xeraphim Nov 22 '19 at 14:47
  • Well without any external lib it's a dead end on the server. Does deserialiszing PublikationsDatum to a string. and have an other property that get it's value from parsing the string once look ok or too ugly? – xdtTransform Nov 22 '19 at 14:51
  • The second question in my comment shows how to change the `JsonResult`, which is what `this.Json()` returns. Better to update your API to return ISO 8601 dates than add code to your consumer to work around a bad design, IMO. – Heretic Monkey Nov 22 '19 at 16:55

1 Answers1

1

The number within /Date( and )/ is the milliseconds since the UNIX epoch.

You can make a custom converter like this:

public class DateTimeConverter : JsonConverter<DateTime>
{

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // You should do some fool proof parsing here
        var s = reader.GetString();
        s=s.Replace("/Date(","").Replace(")/","");
        long epoch = Convert.ToInt64(s);
        DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(epoch);
        return dateTimeOffset.UtcDateTime;
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        // Do some conversion here
    }
}

Here is a .net fiddle: https://dotnetfiddle.net/tAK62c

Palle Due
  • 5,929
  • 4
  • 17
  • 32
  • thank you this works! I like that alot better than serializing to a string and having another property parse the string :) – xeraphim Nov 22 '19 at 15:08
  • If the epoch is under the millisecond precision, you will loose it. Not a big deal if not one cars ubt just in case. – xdtTransform Nov 22 '19 at 15:21