1

目前我正在尝试在我的项目中使用 Json.Net 序列化程序。

我最近遇到的问题之一是反序列化对象的所有私有列表项都重复了。它可以像这样复制:

  1. 创建具有类型private字段的List<>类,其中List<>泛型参数是其他类
  2. 添加public属性,获取/设置private字段
  3. 创建该类的实例,使用属性将 1 项添加到内部列表。
  4. 使用设置为查看私有类数据的新 DefaultContractResolver 进行序列化;
  5. 反序列化

重现问题的代码:

    public class ClassParam
    {
        public int? ParamOne
        {
            get;
            set;
        }
    }
    public class ClassWithParams
    {
        private List<ClassParam> _privateFieid = new List<ClassParam>();

        public List<ClassParam> PropertWithBackingField
        {
            get { return _privateFieid; }
            set { _privateFieid = value; }
        }
        
        public void AddElementToPrivateField(ClassParam classParam)
        {
            _privateFieid.Add(classParam);
        }
        
    }
    [Test]
    public void Test()
    {
            var instance = new ClassWithParams();

        var param1 = new ClassParam { ParamOne = 1 };

        instance.PropertWithBackingField.Add(param1);

        var contractResolver = new DefaultContractResolver();
        contractResolver.DefaultMembersSearchFlags |= BindingFlags.NonPublic;

        string serializedInstance = JsonConvert.SerializeObject(instance,
                                                                   Formatting.Indented,
                                                                   new JsonSerializerSettings()
                                                                   {
                                                                       ContractResolver = contractResolver
                                                                      
                                                                   });

        var deserializeInstance = JsonConvert.DeserializeObject(serializedInstance, typeof(ClassWithParams),
                                                                         new JsonSerializerSettings()
                                                                         {
                                                                             ContractResolver = contractResolver
                                                                         });
    }

1

PropertWithBackingField当我从中删除公共财产时ClassWithParams,一切正常。当我不使用 ContractResolver 的自定义设置时,问题也消失了。但我确实需要序列化我的类的私有数据,只要不是所有数据都通过公共属性公开。

我的代码有什么问题?是否有任何微妙之处,使用 Json.Net 还是一个错误?

4

2 回答 2

1

对于此代码

var s = JsonConvert.SerializeObject(instance);
var desInst = JsonConvert.DeserializeObject<ClassWithParams>(s);

你的 json 将是{"PropertWithBackingField":[{"ParamOne":1}]}

但是你说在序列化/反序列化中包含私有字段

contractResolver.DefaultMembersSearchFlags |= BindingFlags.NonPublic;

并得到一个json

   {
  "_privateFieid": [
    {
      "ParamOne": 1
    }
  ],
  "PropertWithBackingField": [
    {
      "ParamOne": 1
    }
  ]
 }

所以有两种反序列化,一种 for_privateFieid和一种 forPropertWithBackingField

使用BindingFlags.Public或使用我上面的代码要简单得多。

于 2012-09-27T07:42:47.913 回答
-2

DeserializeInstance方法接收现有实例作为参数。可能它不会创建新实例,而是填充现有实例并返回它。

试着放在ReferenceEquals(instance, deserializedInstance)你的手表上。为了避免数据重复使用不接受现有实例的重载或创建新实例并反序列化它。

于 2012-09-27T06:39:53.910 回答