I am hitting an issue where I have an added string element in my document inside an object that may not exist. When deserializing, All I get is “Object reference not set to an instance of an object.”. I’ve proven it’s the additional field by removing the field from my model and then it deserializes. I need a way to tell Mongo during deserialization that the element may be null or undefined and have it accept it. Is this possible?
Example Model:
document: {
object: [{
field1: ""
field2: ""
}]
}
C# Model Example:
[MongoDB.Bson.Serialization.Attributes.BsonIgnoreExtraElements]
public class Document
{
#nullable enable
public Object? object {get;set;}
#nullable disable
}
[MongoDB.Bson.Serialization.Attributes.BsonIgnoreExtraElements]
public class Object
{
[BsonRepresentation(BsonType.String)]
[BsonDefaultValue("")]
public string field1 { get; set; } = "";
[BsonRepresentation(BsonType.String)]
[BsonDefaultValue("")]
public string field2 { get; set; } = "";
#nullable enable
[BsonRepresentation(BsonType.String)]
[BsonDefaultValue("")]
public string? field3 { get; set; } = "";
#nullable disable
}
I’ve tried removing the BSON attributes as well so the field looked like this:
Welcome to the MongoDB Community Forums. I understand that you’re trying to deserialize a document into a POCO (aka C# object) that has an optional field. This is possible using [BsonIgnoreIfNull].
using System;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
var client = new MongoClient();
var db = client.GetDatabase("test");
var coll = db.GetCollection<Document>("sample_documents");
coll.DeleteMany(Builders<Document>.Filter.Empty);
coll.InsertOne(new Document {Title = "Brave New World"});
coll.InsertOne(new Document {Title = "Much Ado About Nothing", Optional = "The bard rocks!"});
var query = coll.AsQueryable();
foreach (var doc in query.ToList())
{
Console.WriteLine(doc);
}
class Document
{
public ObjectId Id { get; set; }
public string Title { get; set; }
[BsonIgnoreIfNull]
public string Optional { get; set; }
public override string ToString() => $"{Id}: {Title} ({Optional ?? "empty"})";
}
The output of this program is:
63659e1a354ffbbfa202286b: Brave New World (empty)
63659e1a354ffbbfa202286c: Much Ado About Nothing (The bard rocks!)
And the contents of the database is:
test> db.sample_documents.find()
[
{
_id: ObjectId("63659e1a354ffbbfa202286b"),
Title: 'Brave New World'
},
{
_id: ObjectId("63659e1a354ffbbfa202286c"),
Title: 'Much Ado About Nothing',
Optional: 'The bard rocks!'
}
]