Search code examples
c#mongodbmongodb-.net-drivermongodb-csharp-2.0

Flatten [BsonExtraElements] to key value pair json output


I am using [BsonExtraElements] in c# to capture additional data that cannot be mapped to my class.

public class QuestionAnswerClass
{
    public string Name { get;set;}
  
    [BsonExtraElements]
    public Dictionary<string,object> AdditionalData {get; set;}
}

Sample data stored in mongodb

{
 Name: John
 Question1: Answer1
 Question2: Answer2
},
{
 Name: Mary
 Question3: Answer3
 Question4: Answer4
}
 

In my controller, I get the data mongoDB, deserialize it to my QuestionAnswerClass and return output as a JsonResult.

var client = new MongoClient("Credentials here");
var database = client.GetDatabase("db");

var results = database.GetCollection<QuestionAnswerClass>("QuestionAnswers").AsQueryable().ToList();
return new JsonResult(results);

Json output is as follow

[
 {
  Name: John
  AdditionalData: {
    Question1: Answer1,
    Question2: Answer2
  }, 
 {
  Name: Mary
  AdditionalData: {
    Question3: Answer3,
    Question4: Answer4
  },
 }
]

Question: How can I flatten the output of AdditionalData to it's own keyvaluepair. Example output that I want is below

[
 {
  Name: John,
  Question1: Answer1,
  Question2: Answer2
 }, 
 {
  Name: Mary,
  Question3: Answer3,
  Question4: Answer4 
 }
]

Solution

  • System.Text.Json (and JSON.NET for anyone else reading) supports an attribute called [JsonExtensionData].

    You can declare it like this in your model:

    [JsonExtensionData]
    public Dictionary<string, object> ExtensionData { get; set; }
    

    And it will serialize the dictionary key/values as properties in the parent object. So if we take your object and add this attribute:

    public class QuestionAnswerClass
    {
        public string Name { get;set;}
      
        [JsonExtensionData]
        [BsonExtraElements]
        public Dictionary<string,object> AdditionalData {get; set;}
    }
    

    We'll get the expected output:

    [
      {
        "Name": "John",
        "Question1": "Answer1",
        "Question2": "Answer2"
      },
      {
        "Name": "Mary",
        "Question3": "Answer3",
        "Question4": "Answer4"
      }
    ]
    

    Try it online