C# - Deserialize String That May Not Exist

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:

#nullable enable
      public string? field3 { get; set; } = "";
#nullable disable

That did not seem to work any better. Any direction would be appreciated.

NOTE: I updated to MongoDB.Driver version 2.18.0 to make sure that would not resolve it.

Hi, @gvanriper,

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!'
  }
]

Hopefully this answers your question.

Sincerely,
James

Thanks, @James_Kovacs . Can confirm this worked. I had sworn I tried that but who knows? Brain fatigue. Thank you for the solution!

Glad I could help. Thanks for letting us know that the solution worked for you.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.