-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
[SUGGESTION] Robust Json serialization #1793
Comments
@ConiJB I think a better solution would be to change https://github.com/mbdavid/LiteDB/blob/5d88c20a14f962e685d255347b3d407d38538248/LiteDB/Document/Json/JsonReader.cs#L83 into something like this: case TokenType.Int:
{
try
{
return new BsonValue(Convert.ToInt32(token.Value, _numberFormat));
}
catch(OverflowException)
{
return new BsonValue(Convert.ToInt64(token.Value, _numberFormat));
}
} |
IMHO, exceptions are better be avoided. They are (1) expensive, (2) noise on debugging, (3) not recommended for normal scenarios in any case. |
@nightroman You are correct, it is better to avoid using exceptions for flow control if possible (I forgot about that). That said, I believe the best solution would be this: case TokenType.Int:
{
if (Int32.TryParse(token.Value, NumberStyles.Any, _numberFormat, out int result))
return new BsonValue(result);
else
return new BsonValue(Int64.Parse(token.Value, NumberStyles.Any, _numberFormat));
} |
@lbnascimento thanks for the reply, it does make sense to use Int64 and not double as proposed. I also agree with @nightroman that exceptions are too expensive and should be avoided. |
@ConiJB If you really need a double, you could simply take the result of |
@lbnascimento Thanks, unfortunatly that's not as easy: I am not deserializing single values but fairly large objects. I do not know beforehand which values and what kind of values are in those documents. Especially I do not know which values are supposed to be double and which ones Int64. |
@ConiJB You could use our var result = BsonMapper.Global.Deserialize<MyClass>(JsonSerializer.Deserialize(jsonString)); If it doesn't have a known structure, you could simply use |
Is your feature request related to a problem? Please describe.
When serializing large doubles using a different Json serializer (Google.Protobuf.JsonFormatter) the decimal places are omitted when the double has no rest. The LiteDB.JsonSerializer detects this as an int32 and throws an exception if this is larger than int32.MaxValue.
So this
throws a "System.OverflowException" with "Value was either too large or too small for an Int32". This behaviour is of course not wrong, but I think it's a very simple change to detect this and change the conversion to double.
Describe the solution you'd like
If you include a simple check in "Tokenizer.cs" at the end of "ReadNumber(ref bool db)" that tries to convert large numbers into Int32 and returns dbl=true if it cannot this serializes more robust for these edge cases.
Describe alternatives you've considered
I tried to bring Google.Protobuf.JsonFormatter to keep the decimal point for all doubles (same as Newtonsoft serializer behaves) but failed.
The text was updated successfully, but these errors were encountered: