使用DataContractJsonSerializer反序列化时控制对象的创建

时间:2018-08-17 18:43:50

标签: c# .net serialization datacontractjsonserializer

我正在使用DataContractJsonSerializer对JSON字符串进行序列化/反序列化。我的对象包含一个Dictionary<string, string>数据成员,并且我想使该字典在反序列化后不区分大小写。当前,在ReadObject之后,我用StringComparer.OrdinalIgnoreCase手动创建了一个新的字典,并将内容复制到新的字典中。这看起来很丑。有什么办法可以更优雅地做到这一点?像反序列化时控制对象创建一样?

1 个答案:

答案 0 :(得分:0)

只要预分配了返回的集合,数据协定序列化程序就可以序列化和反序列化仅获取集合属性。 (这与cannot be serialized directly的其他类型的仅获取属性形成对比。)但是,由于未调用数据协定对象的构造函数,因此有必要在其他地方进行预分配,例如在OnDeserializing method中或在吸气剂中:

[DataContract]
public class RootObject
{
    Dictionary<string, string> dictionary;

    [DataMember]
    public Dictionary<string, string> Dictionary
    {
        get
        {
            if (dictionary == null)
                System.Threading.Interlocked.CompareExchange(ref dictionary, new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase), null);
            return dictionary;
        }
        // DO NOT ADD A SET METHOD EVEN IF PRIVATE, it will break data contract serialization.
    }
}

Dictionary数据成员现在将反序列化为使用Dictionary<string, string>的预先分配的StringComparer.OrdinalIgnoreCase

注意:

  • 不能 是一种设置方法,甚至是私有方法。如果有的话,数据协定序列化程序将构建自己的Dictionary<string, string>并将其重新设置,而忽略预分配的字典。

  • 由于调用了collection data contract objects 的默认构造函数,因此您可以代替Dictionary<string, TValue>的子类,并在构造函数中设置适当的比较器,例如如下:

    public class OrdinalIgnoreCaseDictionary<TValue> : Dictionary<string, TValue>
    {
        public OrdinalIgnoreCaseDictionary() : base(StringComparer.OrdinalIgnoreCase) { }
    }
    
    [DataContract]
    public class RootObject
    {
        [DataMember]
        public OrdinalIgnoreCaseDictionary<string> Dictionary { get; set; }
    }