【问题标题】:How to create custom serializer for values in dictionary?如何为字典中的值创建自定义序列化程序?
【发布时间】:2021-07-14 01:15:49
【问题描述】:

我有以下课程:

 public class Farm
 {
   public string County {get;set;}
   
   public Dictionary<string, object> FarmItems {get;set;}
 }

我需要实现一个自定义的序列化器/反序列化器,如果它的值是整数,则将其作为字符串存储在数据库中,然后将其反序列化回整数

我查看了文档,他们详细说明了如何为单个值而不是字典 https://mongodb.github.io/mongo-csharp-driver/2.12/reference/bson/serialization/

另外,文档没有提到如何实现它,我只是在创建我的类之后添加一个属性:

[BsonSerializer(typeof(MyCustomSerializer))]
public Dictionary<string, object> FarmItems {get;set;}

【问题讨论】:

    标签: c# mongodb bson


    【解决方案1】:

    给你:

    public class MyDictionarySerialzer : SerializerBase<Dictionary<string, object>>
    {
        public override void Serialize(BsonSerializationContext ctx, BsonSerializationArgs args, Dictionary<string, object> dictionary)
        {
            if (dictionary == null)
            {
                ctx.Writer.WriteStartArray();
                ctx.Writer.WriteEndArray();
                return;
            }
    
            ctx.Writer.WriteStartArray();
    
            foreach (var kvPair in dictionary)
            {
                ctx.Writer.WriteStartDocument();
    
                ctx.Writer.WriteName("k");
                ctx.Writer.WriteString(kvPair.Key);
    
                ctx.Writer.WriteName("v");
                if (kvPair.Value is int)
                    ctx.Writer.WriteString(kvPair.Value.ToString());
                else
                    BsonSerializer.Serialize(ctx.Writer, kvPair.Value);
    
                ctx.Writer.WriteEndDocument();
            }
    
            ctx.Writer.WriteEndArray();
        }
    
        public override Dictionary<string, object> Deserialize(BsonDeserializationContext ctx, BsonDeserializationArgs args)
        {
            Dictionary<string, object> dict = new();
    
            switch (ctx.Reader.CurrentBsonType)
            {
                case BsonType.Array:
                    foreach (var val in BsonSerializer.Deserialize<BsonArray>(ctx.Reader))
                    {
                        string key = val["k"].AsString;
                        object value = BsonSerializer.Deserialize<object>(val["v"].ToJson());
    
                        if (int.TryParse(value?.ToString(), out var parsedInt))
                            value = parsedInt;
    
                        dict.Add(key, value);
                    }
                    return dict;
    
                default:
                    throw new BsonSerializationException("Unable to deserialize dictionary!");
            }
        }
    }
    

    如果您在字典值中存储任何复杂实体,则必须像这样使用 mongo 驱动程序注册(在应用启动时)该复杂类型(否则反序列化将失败):

    BsonClassMap.RegisterClassMap<ComplexItem>();
    

    只需像这样装饰属性:

    public class Farm
    {
        [BsonSerializer(typeof(MyDictionarySerialzer))]
        public Dictionary<string, object> FarmItems { get; set; }
    }
    

    示例实体:

    var example = new Farm
    {
        FarmItems = new Dictionary<string, object>()
        {
            {"empty",null },
            {"string","test string" },
            {"int",100 },
            {"complex",new ComplexItem{ Age = 10, Name = "test" } }
        }
    };
    

    它将像这样被序列化到数据库中:

    {
        "FarmItems" : [
            {
                "k" : "empty",
                "v" : null
            },
            {
                "k" : "string",
                "v" : "test string"
            },
            {
                "k" : "int",
                "v" : "100"
            },
            {
                "k" : "complex",
                "v" : {
                    "_t" : "ComplexItem",
                    "Name" : "test",
                    "Age" : 10
                }
            }
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-27
      • 2019-11-27
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      相关资源
      最近更新 更多