2

我有一个自定义的 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 在第二遍时不会被击中?

4

1 回答 1

3

DefaultContractResolver类缓存每个对象类型的合约以获得最佳性能。您可以在源代码中看到它在构造函数中创建缓存的位置:

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只会在第一次序列化时调用。

于 2018-09-21T16:36:24.817 回答