bchavez / RethinkDb.Driver

:headphones: A NoSQL C#/.NET RethinkDB database driver with 100% ReQL API coverage.

Home Page:http://rethinkdb.com/api/java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DateTime field in JObject Deserialization

alana1 opened this issue Β· comments

Hello,

I have a changefeed and returns JObject. In the JObject contains the DateTime field. However, the JObject returns the epoch time. When deserializing JObject to strongly type object, any properties with DateTime epoch time is not converted to the original datetime utc format we are expecting. How can I deserialize the jobject and return correct datetime. A sample of the json is below.

{
  "ChatQueueId": 1,
  "ChatRequestNo": 0,
  "DeliveredTime": {
    "$reql_type$": "TIME",
    "epoch_time": -62135596800,
    "timezone": "+00:00"
  },
  "EmailAddress": "mham@ctintegrations.com",
  "EndTime": {
    "$reql_type$": "TIME",
    "epoch_time": 1472074019.588,
    "timezone": "+00:00"
  },
  "EstablishedTime": {
    "$reql_type$": "TIME",
    "epoch_time": -62135596800,
    "timezone": "+00:00"
  },
  "FirstName": "Jerry",
  "InitialMessage": null,
  "KeyValues": [
    {
      "Key": "defid",
      "Value": "5454564"
    },
    {
      "Key": "defid",
      "Value": "5454564"
    },
    {
      "Key": "defid",
      "Value": "5454564"
    }
  ],
  "LastName": "McGiver",
  "RequestTime": {
    "$reql_type$": "TIME",
    "epoch_time": 1472070419.588,
    "timezone": "+00:00"
  },
  "SiteId": 0,
  "id": "70f6d8a0-4375-41f1-9db9-129683b7f3a1"
}

Just a few questions:

  • DO include the driver version you are using.
  • DO describe the operating system for the Server and Client (Windows / Linux). Also, the run-time platform and versions (.NET Framework/.NET Core/Mono).

Also, are you customizing the Newtonsoft.Json serializer? If so, can you post your configuration? Thanks.

Hello,

I am using C# driver version 2.3.9.0. RethinkDB for Windows version 2.3.4. I am not using customized serializer.

  • Could you update to the latest driver version v2.3.14?
  • Are you using .NET Core or .NET Full?
  • Is the driver running on windows also?
  • What version is the Newtonsoft.Json dependency?

Hey @alana1 ,

This must be due to something else... (like customizing the serializer) the following unit test passes in the C# driver currently:

[Test]
public void try_basic_datetime_deseralization()
{
    var obj = new JObject
        {
            ["Name"] = "Brian",
            ["dob"] = DateTime.Parse("8/24/2016")
        };

    var fromDb = R.Expr(obj).RunResult<JObject>(conn);
    var dateTimeValue = fromDb["dob"] as JValue;
    dateTimeValue.Type.Should().Be(JTokenType.Date);
    dateTimeValue.Value.Should().BeOfType<DateTime>();
}

Protocol Trace

TRACE JSON Send: Token: 3, JSON: [1,{"Name":"Brian","dob":{"$reql_type$":"TIME","epoch_time":1472022000.0,"timezone":"-07:00"}},{}]
TRACE JSON Recv: Token: 3, JSON: {"t":1,"r":[{"Name":"Brian","dob":{"$reql_type$":"TIME","epoch_time":1472022000,"timezone":"-07:00"}}]}

So we are converting the time pseudo types correctly with JObject. You'll have to send me a PR with a failing unit test in order to debug this more. πŸ˜•

⏳ πŸ” _"But I still haven't found what I'm for..."_

I am using RunChanges(conn). Is that okay?

Ahhhh. Okay, that makes sense now. Yeah, that would be a bug in the driver.

.RunChanges is a wrapper for .RunCursor<Change<JObject>> which is just like the gotcha above; except this on is on meeee!!!! πŸ›

Haha, okay, I'll work on getting a fix for you soon.

⌚ πŸŒ† _"I just can't wait... I just can't wait... for saturday night..."_

Thank you and much appreciated.

Hey @alana1 , as a temporary workaround, instead of using .RunChanges<JObject>(conn), could you use .RunCursor<JObject>(conn) instead? It's pretty much the same thing, and it will resolve your issue temporarily.

I'm going to need a little more time to think about how to resolve this issue effectively in C#; it's turning out to be a more tricky problem with the type system than I originally thought.

Hello @bchavez, your suggestion worked. Thank you for your help on this.

Hey @alana1 so I gave this a lot of thought. I really tried every trick in my book to think this one through for a clean performant implementation....

I decided that we're not going to support JObject in the RunChanges<JObject> run helper. The reasoning is because the generic type parameter open-endedness really complicates the code to check for nested JToken types. For example,

.RunChanges<JObject>()
.RunChanges<List<JObject>>()
.RunChanges<Tuple<JObject, JArray>>>()
... and on. and on.

So, I think the best we can do is document this behavior in the GOTCHA! and recommend that developers use .RunCursor<JObject>() instead of .RunChanges<JObject> as I've shown you above. .RunChanges<T> should really be only for POCO strongly typed conversions from JSON to T POCO.

πŸ”₯ πŸŒ‹ _"We're building it up, to break it back down..."_