1

I am in Mongo-C# environment and using 10Gen Mongo driver. i am facing a problem when I am trying to deserialize the data inside the Mongo document when it has a sub document and that sub document is not strongly typed. In other words, if the sub document is an Expando or simply an anonymous object() then it give errors out while deserializing with the following error:

System.IO.FileFormatException: A document being deserialized to System.Object must be empty.

We I can put a filter before and after the Mongo read/write which converts my Object into a BSONDocument on the fly but I think there is not cast available between BSOnDocument and (Expando or anonymous type).

Writting a custom deserialization tool sounds like too much work for this. I am just wondering is someone has faced this problem before and how they have handled this problem?

Lost
  • 12,007
  • 32
  • 121
  • 193

2 Answers2

1

Currently, since the 10gen driver is based on .NET 3.5, we do not support dynamic objects. Currently, the way to handle this is using an ExtraElements member. You can read about it here: http://www.mongodb.org/display/DOCS/CSharp+Driver+Serialization+Tutorial#CSharpDriverSerializationTutorial-Supportingextraelements.

We will be supporting .NET 4.0 in full at a later date and with that will come full support for dynamic objects. If you really need the feature now, you can see my spike of side-by-side support using another assembly here: https://github.com/craiggwilson/mongo-csharp-driver/tree/dynamic. However, it is untested and is truly just a spike, so be wary.

Craig Wilson
  • 12,174
  • 3
  • 41
  • 45
  • I can see your point here. But my problem here is that my input of the module is basically an expando object and the output is also expecting an expando to process. In this case, even though I end up saving a BSON Document in Mongo, I need to figure out a casting mechanism from Mongo to BSON and visa versa..... – Lost Jun 01 '12 at 16:34
  • If you are always using Expandos, then you can create a custom IBsonSerializer to handle the conversion to and from an Expando. You can use db.GetCollection("name") to get them in and out. Since Expando implements IDictionary, then you can simply defer your methods internally to the DictionaryGenericSerializer. In master is actually some code that already does this (with regards to IDictionary so you wouldn't need this). Until then... – Craig Wilson Jun 01 '12 at 16:46
  • Trying to do that gives me follwing error:`Element '_id' does not match any field or property of class System.Dynamic.ExpandoObject.` – Lost Jun 01 '12 at 17:39
  • `var expando = db.GetCollection("QueuedMessage"); var message = expando.FindOne(); I tried something like that.` – Lost Jun 01 '12 at 17:40
  • Speaking of your code that you send me link to. All I need is DynamicBsonSerializer.cs? and can call Deserialize function on that? – Lost Jun 01 '12 at 17:59
  • Where do I pass my MongoDocument here? `Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)` – Lost Jun 01 '12 at 18:24
  • If you implement IBsonSerializer and register it, then as long as you set an _id manually on your expando object, it should be fine. Could you post the code you used that caused the exception. Regarding my spike code, that is kinda the issue. "dynamic" isn't a real type, so you have to pass it typeof(object). – Craig Wilson Jun 01 '12 at 19:33
  • Well, i kind of took a detour. I figured that Mongo has problem with Anonymous types and Expando objects. But it treats iDictionary very well. I actually put two parsers ToDictionary() and ToExpando() in from of my input and output tunnel and it is working great now. In short, Convert expando to a Dictionary before it goes to database and convert Dictionary into an expando as soon as it comes out of database. – Lost Jun 01 '12 at 23:38
0

If you want to store dynamic / anonymous types you can use a custom IBsonSerializer.

See https://stackoverflow.com/a/23244044/327825 for code samples

Community
  • 1
  • 1
Rolf Wessels
  • 797
  • 9
  • 12