[CSHARP-417] BsonArray doesn't support null values Created: 27/Mar/12  Updated: 02/Apr/15  Resolved: 10/Apr/12

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 1.4
Fix Version/s: 1.4.1

Type: Bug Priority: Major - P3
Reporter: Ben Blamey Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: crash
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Looking at the source code for BsonArray.cs, there are numerous places where null values in the array will cause a crash.

line 676:
clone.Add(value.DeepClone());

line 722:
hash = 37 * hash + value.GetHashCode();

line 818:
sb.Append(_values[i].ToString());

line 833:
_values[i].WriteTo(bsonWriter);

..and I'm sure there are other places!

To reproduce: deserialize some JSON with a null in an array, then try adding to Mongo with the driver.

My understanding is that null values are valid JSON and valid BSON, so should be supported by Mongo and the C# driver.

I'm happy to work on this - but am too busy this week.

Thanks,
Ben



 Comments   
Comment by Robert Stam [ 10/Apr/12 ]

When mapping from .NET data types to BsonDocument object model null is mapped to BsonNull.Value. When creating BsonValues using functional construction null is ignored.

Comment by Ben Blamey [ 28/Mar/12 ]

Cracking.

My scenario is pretty typical: I want to store a JsonObject (from SimpleJson) in a Mongo database - thats the object I get back from a different API. That object is cast to an IDictionary<,> - so I want to faithfully preserve the underlying original JSON document (which I don't have). It would suit me best (and be most logical) if construction from IDictionary<,> follow JSON principles of keeping nulls.

Thanks.

Comment by Robert Stam [ 27/Mar/12 ]

Thanks for the test case.

The fix should probably be in the caller to BsonValue.Create, but I'll evaluate that more carefully when I get to this.

The reason it's not clear cut is that the BsonDocument object model follows the functional construction pattern used by XDocument, where null is used to mean skip this item.

In any case, a NullReferenceException is definitely not the right behavior!

Comment by Ben Blamey [ 27/Mar/12 ]

Hi Robert - Sorry for jumping to conclusions - should have RTFM!!

Anyway, I do actually get an exception with nulls.....I've made a failing test case:

var dict1 = new Dictionary<string, object>() { { "foo", new object[]

{ null }

} };
var document1 = new UpdateDocument(dict1);
document1.ToBson();

Looks to me like the prob lem is BsonValue.cs : public static BsonValue Create(object value)

if (value == null)

{ return null; // Should be a BsonNull? }

..Which presumably is how the null ends up inside the document

Here is the stack trace:

System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=MongoDB.Bson
StackTrace:
at MongoDB.Bson.BsonArray.WriteTo(BsonWriter bsonWriter) in D:\code\mongo-csharp-driver\Bson\ObjectModel\BsonArray.cs:line 833
at MongoDB.Bson.BsonValue.WriteTo(BsonWriter bsonWriter) in D:\code\mongo-csharp-driver\Bson\ObjectModel\BsonValue.cs:line 1230
at MongoDB.Bson.BsonElement.WriteTo(BsonWriter bsonWriter) in D:\code\mongo-csharp-driver\Bson\ObjectModel\BsonElement.cs:line 276
at MongoDB.Bson.BsonDocument.Serialize(BsonWriter bsonWriter, Type nominalType, IBsonSerializationOptions options) in D:\code\mongo-csharp-driver\Bson\ObjectModel\BsonDocument.cs:line 1041
at MongoDB.Bson.Serialization.BsonSerializer.Serialize(BsonWriter bsonWriter, Type nominalType, Object value, IBsonSerializationOptions options) in D:\code\mongo-csharp-driver\Bson\Serialization\BsonSerializer.cs:line 561
at MongoDB.Bson.BsonExtensionMethods.ToBson(Object obj, Type nominalType, IBsonSerializationOptions options, BsonBinaryWriterSettings settings) in D:\code\mongo-csharp-driver\Bson\BsonExtensionMethods.cs:line 124
at MongoDB.Bson.BsonExtensionMethods.ToBson(Object obj, Type nominalType, BsonBinaryWriterSettings settings) in D:\code\mongo-csharp-driver\Bson\BsonExtensionMethods.cs:line 139
at MongoDB.Bson.BsonExtensionMethods.ToBson(Object obj, Type nominalType) in D:\code\mongo-csharp-driver\Bson\BsonExtensionMethods.cs:line 91
at MongoDB.Bson.BsonExtensionMethods.ToBson[TNominalType](TNominalType obj) in D:\code\mongo-csharp-driver\Bson\BsonExtensionMethods.cs:line 40
.. my code..
InnerException:
(none)

Comment by Robert Stam [ 27/Mar/12 ]

BSON/JSON nulls are supported by the C# driver and are represented in the BsonDocument object model by the BsonNull.Value singleton (not with a C# null).

For example, the following code works:

var json = "{ x : 1, a : [ 1, null ] }";
var document = BsonDocument.Parse(json);
Console.WriteLine(document.ToJson());

and outputs

{ "x" : 1, "a" : [1, null] }

Have you actually gotten a NullReferenceException from any of the above lines?

Comment by Ben Blamey [ 27/Mar/12 ]

I'm looking at the code at this commit:
8c7909d4a24a5388a67174a43c3773b142602e9b BUMP 1.4.0.4468

Generated at Wed Feb 07 21:36:46 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.