-
-
Save lurumad/410e05154cc7e9f2f3eb to your computer and use it in GitHub Desktop.
public class TempDataDocument | |
{ | |
[BsonRepresentation(BsonType.ObjectId)] | |
public string Id { get; set; } | |
[BsonElement("key")] | |
public string Key { get; set; } | |
[BsonElement("value")] | |
[BsonSerializer(typeof(CustomSerializer))] | |
public object Value { get; set; } | |
} | |
public class CustomSerializer : IBsonSerializer | |
{ | |
#region Implementation of IBsonSerializer | |
public object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options) | |
{ | |
return Deserialize(bsonReader, nominalType, null, options); | |
} | |
public object Deserialize( | |
MongoDB.Bson.IO.BsonReader bsonReader, | |
Type nominalType, | |
Type actualType, | |
IBsonSerializationOptions options) | |
{ | |
if (bsonReader.GetCurrentBsonType() != BsonType.Document) | |
{ | |
throw new Exception("Not document"); | |
} | |
var bsonDocument = BsonSerializer.Deserialize(bsonReader, typeof(BsonDocument), options) as BsonDocument; | |
var cleanJson = Regex.Replace(bsonDocument.ToJson(), @"ObjectId\((.[a-f0-9]{24}.)\)", (m) => m.Groups[1].Value); | |
return JsonConvert.DeserializeObject<object>(cleanJson); | |
} | |
public IBsonSerializationOptions GetDefaultSerializationOptions() | |
{ | |
return new DocumentSerializationOptions(); | |
} | |
public void Serialize(MongoDB.Bson.IO.BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) | |
{ | |
var json = (value == null) ? "{}": JsonConvert.SerializeObject(value); | |
BsonDocument document = BsonDocument.Parse(json); | |
BsonSerializer.Serialize(bsonWriter, typeof(BsonDocument), document,options); | |
} | |
#endregion | |
} | |
void Main() | |
{ | |
var client = new MongoClient("mongodb://localhost:27017"); | |
var server = client.GetServer(); | |
var database = server.GetDatabase("mvc"); | |
var collection = database.GetCollection("tempdata"); | |
var document = new TempDataDocument() | |
{ | |
Key = "key1", | |
Value = new | |
{ | |
Nombre = "Sergio", | |
Twitter = "@panicoenlaxbox" | |
} | |
}; | |
collection.Insert(document); | |
var data = collection.FindAs<TempDataDocument>(Query.EQ("key", "key1")); | |
Console.WriteLine(data); | |
} |
Gran trabajo, probado y funcionando!!
De todas formas, tengo alguna duda (seguro fruto de mi inexperiencia con MongoDB) He visto en http://docs.mongodb.org/ecosystem/tutorial/serialize-documents-with-the-csharp-driver/#write-a-custom-serializer que supuestamente lo único que hay que hacer es implementar IBsonSerializer, a excepción de este párrafo que podemos obviarlo porque no nos gusta LINQ sobre MongoDB :) "However, there are some extension interfaces that will enable further use in other parts of the api such as saving a class or LINQ"
Para mí algo falla porque no es verdad que sólo haya que hacer eso, por ejemplo con tu código todo funciona a la primera, pero fíjate en que no se está grabando el campo _id en la base de datos. De esta forma, si ejecutas el código una segunda vez te lanza el siguiente error "An unhandled exception of type 'MongoDB.Driver.MongoDuplicateKeyException' occurred in MongoDB.Driver.dll" y yo me pregunto: Si sólo estás decorando la propiedad Value (no la clase entera) ¿Por qué no se graba el _id?
Luego investigaré más en casa, gracias por preocuparte por esto, actualizaré el post seguro luego con todo lo que saquemos, de hecho yo lo estoy utilizando en producción así que estoy muy interesado :)
Yo si que tengo el Id:
/* 0 */
{
"_id" : ObjectId("537b23be3814fe25e8119e01"),
"key" : "key1",
"value" : {
"Nombre" : "Sergio",
"Twitter" : "@panicoenlaxbox"
}
}
/* 1 */
{
"_id" : ObjectId("537b4e733814fe181cd96417"),
"key" : "key1",
"value" : {
"Nombre" : "Sergio",
"Twitter" : "@panicoenlaxbox"
}
}
/* 2 */
{
"_id" : ObjectId("537b4e753814fe181cd96418"),
"key" : "key1",
"value" : {
"Nombre" : "Sergio",
"Twitter" : "@panicoenlaxbox"
}
}
Y no me salta ninguna excepción :(
Pues llevas razón, error mío, luego actualizo el post con una super-mención para un tal lurumad :)
Gracias
Lo he actualizado ;)