jamesnk / newtonsoft.json.bson Goto Github PK
View Code? Open in Web Editor NEWJson.NET BSON adds support for reading and writing BSON to Json.NET
License: MIT License
Json.NET BSON adds support for reading and writing BSON to Json.NET
License: MIT License
Is it ready to use?
It seems Mongo has introduced a new way to store GUID, and they call it Standard.
see https://mongodb.github.io/mongo-csharp-driver/2.11/reference/bson/guidserialization/.
I just tested and check the code.
This version (1.0.2) of Newtonsoft.Json.Bson is not compatible with the Mongo's implementation.
I think this lib should support it as well.
Indeed, I tried to override the BsonDataWriter
and void WriteValue(Guid value)
, but there are two many internal class and method I cannot access.
We did some benchmarks and we got results that we think are counter-intuitive: BsonDataWriter is slower than JsonTextWriter (almost 50% slower). Does it make sense? How can this be explained?
I wanted to use Newton.Json.Bson nuget package in a project Targeting Windows 8.1 Store App. But Newtonsoft.Json.Bson Targets the .NET Standard 1.3 so I can't use it. Because only .NET Standard 1.2 is supported.
So my question is there a reason why .NET Standard 1.3 was used and if not can Newtonsoft.Json.Bson be retargeted to .Net Standard 1.2
Hello James,
We are trying to use Bson but our Json version is not compatible with it, which is causing runtime issues. When(if) this nuget going to be compatible with Newtonsoft.Json?
Thanks.
@JamesNK: You closed issue #9 as limitation of BSON. Could you elaborate on this? As far as I see in the specification (http://bsonspec.org/spec.html) it is easily possible to differentiate between objects and arrays.
Do you want to request a feature or report a bug?
bug
The precision of the DateTime and DateTimeOffset serialization seems to loose precision while in BSON.
What is the current behavior?
When I store and retrieve a DateTime or a DateTimeOffset object, I expect it to store the microseconds all the way to 7 decimal places. Otherwise this causes issues in our production systems.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem
Here's a test method to demonstrate the point. If you put a breakpoint on the "Assert", you can see the two timestamps are different.
public class ItemData
{
public DateTime CreationTime { get; set; }
public DateTime? UpdateTime { get; set; }
public DateTimeOffset? TimeSinceLastPublish { get; set; }
public DateTimeOffset DueDate { get; set; }
}
[Test]
public void Serialize()
{
ItemData c = new ItemData
{
CreationTime = DateTime.Now,
UpdateTime = null,
DueDate = DateTimeOffset.Now + TimeSpan.FromHours(2),
TimeSinceLastPublish = null,
};
MemoryStream ms = new MemoryStream();
JsonSerializer serializer = new JsonSerializer();
// serialize product to BSON
BsonDataWriter writer = new BsonDataWriter(ms);
serializer.Serialize(writer, c);
ms.Position = 0;
BsonDataReader reader = new BsonDataReader(ms);
ItemData test = serializer.Deserialize<ItemData>(reader);
Assert.AreEqual(c.UpdateTime, test.UpdateTime);
Assert.AreEqual(c.DueDate, test.DueDate);
}
What is the expected behavior?
Both timestamp results should be exactly the same up to the microseconds (7 decimal places)
What is the actual behavior?
For example in the above unit test, it only keeps 3 digits of the precision. This is not an issue with the standard JSON processor.
Message: Expected: 2018-12-26 18:59:19.2126799-08:00
But was: 2018-12-26 18:59:19.212-08:00
What is the motivation / use case for changing the behavior?
We are getting a number of bugs based on resolution of DateTime in our product Akavache https://github.com/reactiveui/akavache.
We came up with a hacky solution in the following PR reactiveui/Akavache#448 but ideally would want a proper fix. Our fix would likely not be compatible with other BSON reader/writers since we use the .NET DateTime tick.
Which versions of Newtonsoft.Json.BSON are you using?
1.0.2
Windows 10
C# Framework .Net Core 2.1
Hello,
I'm trying to store a large amount of data as binary JSON and later load them one by one.
But it's not working with FileStream
, according to unit tests it works correctly with MemoryStream
.
Example:
class MyClass
{
public string Msg { get; set; }
public int Year { get; set; }
}
public static void Test()
{
var obj1 = new MyClass { Msg = "1", Year = 2018 };
var obj2 = new MyClass { Msg = "2", Year = 2019 };
var fsWrite = new FileStream("my_file", FileMode.Append);
var writer = new BsonDataWriter(fsWrite);
using (writer)
{
var serializer = new JsonSerializer();
serializer.Serialize(writer, obj1);
serializer.Serialize(writer, obj2);
}
var fsRead = new FileStream("my_file", FileMode.Open);
var reader = new BsonDataReader(fsRead)
{
SupportMultipleContent = true
};
using (reader)
{
var serializer = new JsonSerializer();
while (reader.Read())
{
var deserialized = serializer.Deserialize<MyClass>(reader);
// called only once and deserialized == obj1
}
}
}
Did I miss something?
UPDATE
I've tried code from unit test (with MemoryStream
) and it also doesn't work (second object tst2A
is null).
I run the code inside console application and <TargetFramework>netcoreapp2.1</TargetFramework>
.
Newtonsoft.Json.Bson: 1.0.1
Newtonsoft.Json: 11.0.2
UPDATE 2
It's working with prerelease version 1.0.2-beta1
!
Hi,
Our SCA tool is reporting high severity security issue as Newtonsoft.Json.Bson is referring to Newtonsoft.Json version < 13.0.1. We have noticed that you have fixed the issue under JamesNK/Newtonsoft.Json#2535 for Newtonsoft.Json.
Could you please let us know if you have plan to upgrade Newtonsoft.Json used by Newtonsoft.Json.Bson to 13.0.1?
Is it planned or this package is obosolete and abandoned? If not, maybe it is time to mark this repository as not maintained anymore?
When using BsonDataWriter/BsonDateReader collections serialized can not be deserialized as the same type. It looks, that they are stored as objects.
Steps to reproduce:
void Main()
{
var target = new T[] { new T{ V = 1 }, new T{ V = 2 }, new T{ V = 3 }};
var s = new MemoryStream(100);
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(Console.Out, target); // As expected: [{"V":1},{"V":2},{"V":3}]
using (var writer = new BsonDataWriter(s) { CloseOutput = false })
{
serializer.Serialize(writer, target);
}
s.Position = 0;
using (var reader = new BsonDataReader(s) { CloseInput = false })
{
// dynamic x = serializer.Deserialize(reader);
// Console.WriteLine(JsonConvert.SerializeObject(x)); // Why?!: {"0":{"V":1},"1":{"V":2},"2":{"V":3}}
var deserialized = serializer.Deserialize<T[]>(reader);
/* EXCEPTION
JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'T[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path '0'.
*/
}
}
class T { public int V { get; set; } }
The BSON specification at (http://bsonspec.org/spec.html) has a datatype for decimal. The current implementation does not properly support this. The BsonWriter will write a decimal value as a BsonType.Number which is a double and therefore my decimal precision is lost.
I tried subclassing the BsonWriter, but it doesn't look like I can extend the classes to add this support.
Are there plans to support the decimal datatype?
Any other way I can use bson and work with decimals?
Hey,
I run into a problem but it is maybe also JSON related, not only BSON.
[Serializable]
public class CustomCollection<T> : Collection<T>, ISerializable
{
public CustomCollection(string name)
{
Name = name;
}
protected CustomCollection(SerializationInfo info, StreamingContext context)
{
Name = info.GetValue("$$Name", typeof(string)).ToString();
// more deserialisation in real impl
}
public string Name { get; private set; }
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("$$Name", Name, typeof(string));
// more serialisation in real impl
}
}
[TestMethod]
public void Custom_SerializationDeserialization()
{
var serializer = new JsonSerializer
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
};
var expected = new CustomCollection<string>("Foo");
byte[] buffer;
using (var ms = new MemoryStream())
{
using (var writer = new BsonDataWriter(ms))
{
serializer.Serialize(writer, expected);
buffer = ms.ToArray();
}
}
CustomCollection<string> actual;
using (var ms = new MemoryStream(buffer))
{
using (var reader = new BsonDataReader(ms))
{
actual = serializer.Deserialize<CustomCollection<string>>(reader);
}
}
Assert.AreEqual(expected.Name, actual.Name));
}
Deserialization crashes with
Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type bsontest.CustomCollection`1[System.String]. Path '$values'.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList(JsonReader reader, JsonArrayContract contract, Boolean& createdFromNonDefaultCreator)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
Checking the debugger, I see that GetObjectData
is not called during serialization;
When I don´t inherit from Collection<>
, GetObjectData
is called and deserialization constructor is respected.
Mongo's BsonBinaryWriter
serializes my complex document on the server, and Json.NET's BsonDataReader
deserializes it to a JObject
on the client. After deserialization, I replace _id
ObjectIds
with their string representations and then do the following for references:
foreach ( var reference in rootJObject.Descendants().OfType<JValue>().Where( v => v.Type == JTokenType.Bytes ).ToList() )
reference.Replace( new JObject( new JProperty( "$ref", (string)reference ) ) );
This seems to work but relying on v.Type == JTokenType.Bytes
to recognize the ObjectId
s concerns me. Bytes
is too general and could lead to false positives. I propose to improve the deserialization of BSON to provide a more sure way to recognize the ObjectId
s.
In the original JSON with which I seeded the Mongo database, I represented ObjectId
s in Mongo's strict JSON format of {$oid: "someObjectId"}
. Upon deserializing to JObject
, I propose an option that the ObjectId
s is represented as such instead of the byte representation.
Working directory can be set to e.g. C:\WINDOWS\system32 depending on how Visual Studio was opened, leading to the wrong path being used in the test.
The documentation for Bson does not mention the new classes, only that Bson has moved to a new package.
Issue 1277 over at Newtonsoft.Json helped me in migrating from BsonWriter
and BsonReader
to the new BsonDataWriter
and BsonDataReader
.
Hi,
Currently I get a compiler warning when using the latest version Newtonsoft.Json.Bson because it has a dependency to v10.x of Newtonsoft.Json and I have another Nuget package (MassTransit) in the same project that requires v11.x of Newtonsoft.Json.
When I run my solution I don't seem to have any issues so I the breaking changes in v11 of Newtonsoft.Json does not seem to impact Newtonsoft.Json.Bson. This would mean that, unless I'm missing something, this issue can be fixed with a minor/revision version bump Newtonsoft.Json.Bson in which the NuGet reference to Newtonsoft.Json will be updated to v11.x.
Thanks in advance,
Regards,
Wouter Roos
If you run the code below, you'll see that the two lines written to the console are not the same. The DateTime is being rounded to the nearest millisecond.
DateTime d = new DateTime(123456789012);
Console.WriteLine(d.Ticks);
var serializer = new JsonSerializer();
byte[] buffer;
using (MemoryStream ms = new MemoryStream())
{
using (BsonDataWriter w = new BsonDataWriter(ms))
{
serializer.Serialize(w, new List<DateTime>() { d });
ms.Position = 0;
buffer = ms.ToArray();
}
}
using (MemoryStream ms = new MemoryStream(buffer))
{
using (BsonDataReader r = new BsonDataReader(ms))
{
r.ReadRootValueAsArray = true;
var d2 = (List<DateTime>)serializer.Deserialize(r, typeof(List<DateTime>));
Console.WriteLine(d2[0].Ticks);
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.