Skip to content

Instantly share code, notes, and snippets.

@mahizsas
Last active February 8, 2024 01:45
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mahizsas/de6d44a91af7848d8017 to your computer and use it in GitHub Desktop.
Save mahizsas/de6d44a91af7848d8017 to your computer and use it in GitHub Desktop.
Serilize dynamic data with mongodb
using System;
using System.Collections;
using System.Linq;
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Options;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace TestMongo
{
internal class Program
{
private static void Main(string[] args)
{
var store = new Store("mongodb://localhost:27017/Test__");
var ticket1 = new Ticket
{
CreatedAt = DateTime.Now,
Id = Guid.NewGuid(),
Name = "Test",
Payload = JObject.Parse(JsonHolder.Sample1)
};
var ticket2 = new Ticket
{
CreatedAt = DateTime.Now,
Id = Guid.NewGuid(),
Name = "Test",
Payload = JArray.Parse(JsonHolder.Sample2)
};
var demo = store.Db.GetCollection("DEMO");
demo.Drop();
demo.Insert(ticket1);
demo.Insert(ticket2);
var tickets = demo.AsQueryable<Ticket>();
var one = tickets.First();
Console.WriteLine(one.Payload.ToString());
foreach (var item in tickets)
{
Console.WriteLine(item.Name);
}
}
}
public class Ticket
{
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime CreatedAt { get; set; }
[BsonSerializer(typeof (DynamicSerializer))]
public dynamic Payload { get; set; }
}
public class Store
{
public readonly MongoDatabase Db;
public readonly MongoUrl Url;
public Store(string url)
{
Url = new MongoUrl(url);
Db = new MongoClient(Url).GetServer().GetDatabase(Url.DatabaseName);
}
}
public class DynamicSerializer : IBsonSerializer
{
public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
{
return Deserialize(bsonReader, nominalType, null, options);
}
public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
object document;
dynamic output;
Type type;
var currentBsonType = bsonReader.GetCurrentBsonType();
switch (currentBsonType)
{
case BsonType.Document:
type = typeof (BsonDocument);
document = BsonSerializer.Deserialize(bsonReader, type, options) as BsonDocument;
output = JObject.Parse(document.ToJson(type));
break;
case BsonType.Array:
type = typeof(BsonArray);
document = BsonSerializer.Deserialize(bsonReader, type, options) as BsonArray;
output = JArray.Parse(document.ToJson(type));
break;
default:
throw new ApplicationException(string.Format("Invalid type {0}", currentBsonType));
}
return output;
}
public IBsonSerializationOptions GetDefaultSerializationOptions()
{
return new DocumentSerializationOptions {AllowDuplicateNames = true};
}
public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
var json = (value == null) ? "{}" : JsonConvert.SerializeObject(value).Trim();
if (StartsAndEnds(json, "[", "]"))
{
var array = BsonSerializer.Deserialize<BsonArray>(json);
BsonSerializer.Serialize(bsonWriter, typeof(BsonArray), array, options);
return;
}
var document = BsonDocument.Parse(json);
BsonSerializer.Serialize(bsonWriter, typeof(BsonDocument), document, options);
}
private static bool StartsAndEnds(string value, string start, string end)
{
return value.StartsWith(start, StringComparison.InvariantCultureIgnoreCase) &&
value.EndsWith(end, StringComparison.InvariantCultureIgnoreCase);
}
}
internal static class JsonHolder
{
public static string Sample1 = "{\"autoExpand\":true,\"batchSize\":50,\"connections\":[{\"connectionName\":\"localhost\",\"credentials\":[{\"databaseName\":\"admin\",\"enabled\":false,\"userName\":\"root\",\"userPassword\":\"root\"}],\"defaultDatabase\":\"\",\"serverHost\":\"127.0.0.1\",\"serverPort\":27017,\"sshAuthMethod\":0,\"sshHost\":\"\",\"sshPassphrase\":\"\",\"sshPort\":0,\"sshPrivateKey\":\"\",\"sshPublicKey\":\"\",\"sshUserName\":\"\",\"sshUserPassword\":\"\",\"sslEnabled\":false,\"sslPemKeyFile\":\"\"}],\"disableConnectionShortcuts\":false,\"loadMongoRcJs\":false,\"style\":\"Native\",\"timeZone\":0,\"uuidEncoding\":0,\"version\":\"1.0\",\"viewMode\":1}";
public static string Sample2 = "[{\"autoExpand\":true,\"batchSize\":50,\"connections\":[{\"connectionName\":\"localhost\",\"credentials\":[{\"databaseName\":\"admin\",\"enabled\":false,\"userName\":\"root\",\"userPassword\":\"root\"}],\"defaultDatabase\":\"\",\"serverHost\":\"127.0.0.1\",\"serverPort\":27017,\"sshAuthMethod\":0,\"sshHost\":\"\",\"sshPassphrase\":\"\",\"sshPort\":0,\"sshPrivateKey\":\"\",\"sshPublicKey\":\"\",\"sshUserName\":\"\",\"sshUserPassword\":\"\",\"sslEnabled\":false,\"sslPemKeyFile\":\"\"}],\"disableConnectionShortcuts\":false,\"loadMongoRcJs\":false,\"style\":\"Native\",\"timeZone\":0,\"uuidEncoding\":0,\"version\":\"1.0\",\"viewMode\":1}]";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment