Reputation: 23214
I am trying to combine some Json.NET json serialization with MongoDB. I have a structure similar to this:
public class Master {
...props...
public Detail[] Details {get;set;}
}
public class Detail {
...props...
public dynamic Value {get;set;}
}
In this case I want the Value
property of Detail
to contain dynamic json. There is no schema, I just want to store whatever comes in there.
If I receive this structure via e.g. Asp.NET, the Value property will be deserialized as JObject
if the value is anything else than a primitive such as string
, bool
etc.
Storing that into MongoDB will result in the Value property being saved as a JObject
. I would just like to store it as the original json structure of the value prop.
There are ways to go from JObject
to BsonDocument
. e.g. var doc = BsonDocument.Parse(jobj.ToString());
.
But in such case, I would have to traverse my object structure and do this manually.
(My real structure is also more complex)
I'm now thinking there might be some better way to deal with this? e.g. somehow attach a converter of some sort to the value property so that the Mongo driver knows how to turn this into proper Bson.
What are my options here? I figure it needs to be done on the Bson serializer end of things somehow?
Upvotes: 3
Views: 1124
Reputation: 49945
Yes, you need to explicitly implement conversion between JObject
and BsonDocument
type. You can implement your own converter and use attributes to avoid traversing your C# type structure. Try:
public class Detail
{
[BsonSerializer(typeof(DynamicSerializer))]
public dynamic Value { get; set; }
}
public class DynamicSerializer : SerializerBase<dynamic>
{
public override dynamic Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var myBSONDoc = BsonDocumentSerializer.Instance.Deserialize(context);
return (dynamic)JObject.Parse(context.ToString());
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, dynamic value)
{
var bson = MongoDB.Bson.BsonDocument.Parse(value.ToString());
BsonDocumentSerializer.Instance.Serialize(context, args, bson);
}
}
Upvotes: 5