Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Core.Misc;
Expand All @@ -36,6 +37,11 @@ public IEnumerableSerializerBase(IBsonSerializer<TItem> itemSerializer)
public override TEnumerable Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var reader = context.Reader;
if (reader.GetCurrentBsonType() == BsonType.Null)
{
reader.ReadNull();
return default;
}
reader.ReadStartArray();
var items = new List<TItem>();
while (reader.ReadBsonType() != 0)
Expand Down Expand Up @@ -64,6 +70,11 @@ obj is IEnumerableSerializerBase<TEnumerable, TItem> other &&
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TEnumerable value)
{
var writer = context.Writer;
if (value == null)
{
writer.WriteNull();
return;
}
Comment on lines 70 to +77
writer.WriteStartArray();
foreach (var item in value)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System.Collections.Generic;
using FluentAssertions;
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;
Expand Down Expand Up @@ -101,6 +102,37 @@ public void GetHashCode_should_return_zero()
result.Should().Be(0);
}

[Fact]
public void Serialize_null_should_write_null()
{
var serializer = new ConcreteIEnumerableSerializerBase<IEnumerable<int>, int>(Int32Serializer.Instance);
var document = new BsonDocument();
using var writer = new BsonDocumentWriter(document);
var context = BsonSerializationContext.CreateRoot(writer);
writer.WriteStartDocument();
writer.WriteName("x");

serializer.Serialize(context, new BsonSerializationArgs(), null);

writer.WriteEndDocument();
document["x"].Should().Be(BsonNull.Value);
}

[Fact]
public void Deserialize_null_should_return_default()
{
var serializer = new ConcreteIEnumerableSerializerBase<IEnumerable<int>, int>(Int32Serializer.Instance);
var document = new BsonDocument("x", BsonNull.Value);
using var reader = new BsonDocumentReader(document);
reader.ReadStartDocument();
reader.ReadName("x");
var context = BsonDeserializationContext.CreateRoot(reader);

var result = serializer.Deserialize(context, new BsonDeserializationArgs { NominalType = typeof(IEnumerable<int>) });

result.Should().BeNull();
}

@BorisDog BorisDog May 26, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would be good to have some limited end-to-end testing. By "e2e" here I mean serializing and deserializing a real POCO, using a real expression (without DB).
But not sure where we place such tests now, any ideas @sanych-sun?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It probably should be a Theory with bytes on one side and expected value on the another. We might need such for all serializers.


internal class ConcreteIEnumerableSerializerBase<TEnumerable, TItem> : IEnumerableSerializerBase<TEnumerable, TItem>
where TEnumerable : IEnumerable<TItem>
{
Expand Down