Search code examples
c#mongodbasp.net-coreasp.net-core-webapimongodb-.net-driver

.NET API Error: Type System.Text.Json.JsonElement is not configured as a type that is allowed to be serialized for this instance of ObjectSerializer


I am using .NET Core API and MongoDB as my database. I am trying to create a simple CRUD operation for one collection. The GET method for API is working properly but I am getting an error for POST call. I tried several options available but nothing seems to be working.

The error is below:

MongoDB.Bson.BsonSerializationException: An error occurred while serializing the Metadata property of class Datasparkx_Model.AdminForm.AdminFormModel: Type System.Text.Json.JsonElement is not configured as a type that is allowed to be serialized for this instance of ObjectSerializer.

Model Class =>

public class MyModel
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string? Id { get; set; }
  
    public Object[] Testdata { get; set; }
}

Controller Call =>

[HttpPost(Name = "AddData")]
public async Task<bool> Post(MyModel document)
{
    await _myCollection.InsertOneAsync(document);
}

Javascript call

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
  "testData": [
    {
      "data1": "name",
      "data2": "textfield",
      "data3": true
    },
    {
      "data1": "email",
      "data3": "email",
      "data4": true
    },
    {
      "randomData": "address",
      "newData": false,
      "anyData": "textarea"
    }
  ]
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://localhost:7051/AddData", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

The parameters are passed properly as expected at Controller level but it doesn't add any data in my database and throws the above error.

Can someone please guide me as I am new to MongoDB.


Solution

  • As you declare the Testdata as Object[] type:

    public Object[] Testdata { get; set; }
    

    When the JsonSerializer deserializes the request data, the object in the Testdata will be defined as JsonElement by default. And MongoDB .NET Driver / BsonSerializer does not support (de)serializing the JsonElement.

    Either:

    1. Have the additional implementation to convert JsonElement to BsonElement as @dbc's answer on How to convert JsonElement to BsonDocument efficiently?

    2. Serialize the document via System.Text.Json.JsonSerializer and deserialize with MongoDB.Bson.Serialization.BsonSerializer.

    Note that when you using this approach, you should exclude deserializing Id to prevent the error that Id is not found in the model class. Or you may apply the [BsonIgnoreExtraElements] attribute to the MyModel class.

    using System.Text.Json;
    using System.Text.Json.Serialization;
    using MongoDB.Bson.Serialization;
    
    string serializedJson = JsonSerializer.Serialize(document, new JsonSerializerOptions
    {
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
    });
    
    document = BsonSerializer.Deserialize<MyModel>(json);
    await _collection.InsertOneAsync(document);
    

    Demo

    enter image description here