Reputation: 35
I am trying to migrate my Database from Cosmos to Mongo. When trying to add an entry for an object which has a C# dynamic Type in MongoDB exception is thrown from the API InsertOneAsync() provided by MongoDB.Driver.IMongoCollection Dynamic Type used to work in Cosmos DB.
MongoDB Insertion Code:
_collection.InsertOneAsync(document);
Model:
namespace Entities.Models
{
[BsonIgnoreExtraElements]
public class UPModel
{
[JsonProperty(PropertyName = "_id")]
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string BsonId { get; set; } = string.Empty;
[BsonElement("resource")]
public Resource Resource{ get; set; }
[BsonElement("preference")]
public Preference Preference { get; set; }
}
[BsonIgnoreExtraElements]
public class Resource
{
[BsonElement("id")]
public string Id { get; set; }
[BsonElement("identifiers")]
public dynamic Identifiers { get; set; }
}
[BsonIgnoreExtraElements]
public class Preference
{
[BsonElement("id")]
public string Id { get; set; }
[BsonElement("value")]
public dynamic Value { get; set; }
}
}
Document that needs to be created for this model in the DB:
{
"id":"uniqueIdentifier",
"preference": {
"id": "dummyPreferenceId",
"value": {
"favorites": [
"dummyFavorites1"
]
}
},
"resource": {
"identifiers": {
"userId": 99,
"routeUrl": "dummyRouteURL",
"type": "standard"
},
"id": "dummyResourceId"
}
}
Exception:
MongoDB.Bson.BsonSerializationException
HResult=0x80131500
Message=An error occurred while serializing the Resource property of class UPModel: An error occurred while serializing the Identifiers property of class Resource: Type Newtonsoft.Json.Linq.JObject is not configured as a type that is allowed to be serialized for this instance of ObjectSerializer.
Source=MongoDB.Bson
StackTrace: "Removed for Readability"
Inner Exception 1:
BsonSerializationException: An error occurred while serializing the Resource property of class UPModel: An error occurred while serializing the Identifiers property of class Resource: Type Newtonsoft.Json.Linq.JObject is not configured as a type that is allowed to be serialized for this instance of ObjectSerializer.
Inner Exception 2:
BsonSerializationException: An error occurred while serializing the Identifiers property of class Resource: Type Newtonsoft.Json.Linq.JObject is not configured as a type that is allowed to be serialized for this instance of ObjectSerializer.
Inner Exception 3:
BsonSerializationException: Type Newtonsoft.Json.Linq.JObject is not configured as a type that is allowed to be serialized for this instance of ObjectSerializer.
I am looking for a way to save the dynamic object type of C# in MongoDB
Upvotes: 1
Views: 76
Reputation: 1795
MongoDB throws exception when the Modal has Dynamic field
It throws an exception because MongoDB.Driver
does not support Newtonsoft.Json.Linq.JObject
. In your code the dynamic
type in Resource.Identifiers
and Preference.Value
is being assigned a JObject
, which MongoDB cannot serialize.
I tried with the below code, it successfully saves the dynamic object type of C# in MongoDB as shown in the output below. The code consists of two dynamic fields BsonArray
and BsonDocument
. Here, BsonDocument
which is directly compatible with MongoDB.
static async Task Main(string[] args)
{
try
{
var connectionString = "*****";
var settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));
settings.ServerSelectionTimeout = TimeSpan.FromSeconds(60);
settings.ConnectTimeout = TimeSpan.FromSeconds(30);
var client = new MongoClient(settings);
var database = client.GetDatabase("db1");
var collectionNames = await database.ListCollectionNames().ToListAsync();
if (!collectionNames.Contains("coll1"))
{
await database.CreateCollectionAsync("coll1");
Console.WriteLine("Collection 'coll1' created.");
}
var collection = database.GetCollection<BsonDocument>("coll1");
var dynamicData = new BsonDocument
{
{ "id", "uniqueIdentifier" },
{ "preference", new BsonDocument
{
{ "id", "dummyPreferenceId" },
{ "value", new BsonDocument
{
{ "favorites", new BsonArray { "dummyFavorites1" } }
}
}
}
},
{ "resource", new BsonDocument
{
{ "id", "dummyResourceId" },
{ "identifiers", new BsonDocument
{
{ "userId", 99 },
{ "routeUrl", "dummyRouteURL" },
{ "type", "standard" }
}
}
}
}
};
await collection.InsertOneAsync(dynamicData);
Console.WriteLine("Data inserted successfully!");
var count = await collection.CountDocumentsAsync(FilterDefinition<BsonDocument>.Empty);
Console.WriteLine($"Total documents in 'coll1': {count}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
Output:
Data inserted successfully!
Total documents in 'coll1': 1
Upvotes: 0