Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SimpleJson fails with DateTime used as Dictionary key #5141

Merged
merged 4 commits into from
Aug 20, 2018

Conversation

bording
Copy link
Member

@bording bording commented Apr 6, 2018

Even after the changes @timbussmann made in #5131, it there are some other cases that aren't handled that I think we might want to support.

Currently, if a dictionary key isn't a string, ToString is called on it, and then it's serialized as a string:

SerializeString(key.ToString(), builder);

This breaks things like DateTime since it's not serialized to the correct format. I would think this almost always the wrong thing to do, since most types are not going to produce a valid string from calling `ToString' on it.

@bording bording requested a review from a team April 6, 2018 20:50
@timbussmann
Copy link
Contributor

I would think this almost always the wrong thing to do, since most types are not going to produce a valid string from calling `ToString' on it.

I haven't checked json.net to the details. But at least using objects as a key will result in just calling ToString as well. I could see that we add some special handling about some common types but not really sure how many serializers properly handle custom types with comparison overloads for dictionary key columns?

@bording
Copy link
Member Author

bording commented Apr 9, 2018

@timbussmann I checked this with Json.NET and the test I've added here passes.

However, to handle an arbitrary type as the key, Json.NET requires a TypeConverter or JsonConverter to be written to handle that.

So, that aspect can considered out of scope, but I think handling other primitive types as keys is a reasonable change to make.

@bording bording changed the base branch from release-7.0 to develop May 7, 2018 19:50
@bording bording force-pushed the simplejson-datetime-dictionary branch from f347ae2 to 142a0c1 Compare May 7, 2018 19:52
@timbussmann
Copy link
Contributor

I've added a few additional tests and some potential solutions. I'll write some more information as line comments.

SerializeString(key.ToString(), builder);
{
// alternative approach:
// jsonSerializerStrategy.TrySerializeNonPrimitiveObject(key, out var keyValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this approach works too and can probably even handle Uri as keys (not tested though). It is quite a bit more expensive in case of "regular" key types like int etc, as it will go through the whole TrySerializeNonPrimiteObject path which also includes some reflection. This approach handles additional types besides DateTimes which are:

  • Guids: they work already as proven by the test
  • Enums: they don't work as the deserialization can't handle that
  • Uris: current behavior not tested

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what additional types do we gain from this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably Uris :D or any other type which might be added to this logic in the future (unlikely though).

// jsonSerializerStrategy.TrySerializeNonPrimitiveObject(key, out var keyValue);
// SerializeString((keyValue as string) ?? key.ToString(), builder);

switch (key)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

downside of this approach is they duplicate DateTime serialization logic and that it only handles DateTimes, nothing else (wouldn't profit from types additionally supported by TrySerializeNonPrimiteObject.

@timbussmann
Copy link
Contributor

@Particular/nservicebus-maintainers thoughts?

@timbussmann timbussmann self-assigned this Aug 14, 2018
@bording
Copy link
Member Author

bording commented Aug 14, 2018

If we do gain additional types with the first approach, then I say we go with that one. We're primarily using this in the learning transport, so perf isn't of the utmost importance. Handling more data types seems like the way to go.

@timbussmann timbussmann changed the title [WIP] SimpleJson fails with DateTime used as Dictionary key SimpleJson fails with DateTime used as Dictionary key Aug 20, 2018
@timbussmann
Copy link
Contributor

I think we should go with the current approach. I left the comment about the alternative approach in there in case we have to revisit that code. Thoughts?

@timbussmann timbussmann added this to the 7.1.0 milestone Aug 20, 2018
@bording bording merged commit 85eda59 into develop Aug 20, 2018
@bording bording deleted the simplejson-datetime-dictionary branch August 20, 2018 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants