JsonConvert.SerializeObject-自定义ContracteResolver不多次调用CreateProperty

时间:2018-09-21 15:49:29

标签: json.net jsonconvert

我有一个自定义的ContracteResolver,但结果却无法预测。

使用调试器,我看到序列化解析器的 CreateProperty 方法时,会为每个属性调用该方法。但是,如果我进行了2次调用,则第二次调用不会调用CreateProperty方法。我在CreateProperty中的断点永远不会在第二遍上被击中,而是在第一遍上被击中。

这是我的设置:

IContractResolver contractResolver = new ShouldSerializeContractResolver(fieldsToSerialize, this.Data);
var settings = new JsonSerializerSettings()
{
ContractResolver = contractResolver
};

_payload = JsonConvert.SerializeObject(this.Data, Formatting.None, settings);

两个调用的源值(this.Data)不同。两个调用的结果(_payload)也不同。我认为没有任何东西被缓存。

我看到了由自定义ContentNegotiator引起的类似问题,但我没有使用它。

为什么第二遍不点击CreateProperty?

1 个答案:

答案 0 :(得分:1)

DefaultContractResolver类为每种对象类型缓存协定以获得最佳性能。您可以在source code中看到这一点,它在构造函数内部创建了缓存:

public DefaultContractResolver()
{
   ...
    _contractCache = new ThreadSafeStore<Type, JsonContract>(CreateContract);
}

以及每种类型的合同得到解决时如何使用它:

public virtual JsonContract ResolveContract(Type type)
{
    ValidationUtils.ArgumentNotNull(type, nameof(type));

    return _contractCache.Get(type);
}

所以,如果:

  1. 您的自定义解析器来自DefaultContractResolver
  2. 您每次都使用相同的解析器实例,并且
  3. 您的数据对象具有相同的类型(即使它们具有不同的数据)

这是正常现象,并期望仅在第一次序列化时调用CreateProperty