递归调用时忽略`JsonConverter`属性

时间:2019-03-29 02:31:28

标签: c# json json.net

我编写了一个自定义JsonConverter,如果失败,则使用默认行为尝试JSON解析。受此answer的启发,另一个问题在下面的代码中,并且运行良好。

基本上,在我自己的转换尝试失败后,我的工作是,将类型的序列化器的Converter属性设置为null,调用反序列化(这似乎导致它跳过了转换器,这很好),然后在我的finally子句中将其还原(我在finally子句中执行此操作,因此即使调用了异常,也将还原Converter)。

我的问题是:

  1. JSON.Net传递给此函数的serialiser是否具有共享的“ ContractResolver”或它自己的唯一副本?
  2. 如果它具有自己的唯一副本,我认为这里的finally子句是不必要的吗?
  3. 如果共享了“ ContractResolver”,则我认为我所做的事情绝对是非线程安全的,因为同时发生的来自单独线程的任何反序列化都可能跳过自定义序列化程序,如果恰好发生另一反序列化的情况同时进行(我想必须用锁来解决这个问题)?
  4. 是否有更好的完全不同的方法来解决此问题?
public override object ReadJson (
    JsonReader reader,
    Type objectType,
    object existingValue,
    JsonSerializer serializer) 
    {
        JToken nextToken = JToken.ReadFrom (reader);
        try {
            using (JTokenReader reader1 = new JTokenReader (nextToken))
            {
                // Attempt to parse in custom fashion
            }
        }
        catch (Exception e)
        {
            // If the previous attempt threw, fallback behaviour here:
            using (JTokenReader reader2 = new JTokenReader(nextToken))
            {
                JsonConverter originalConverter = null;
                JsonContract contract = serializer.ContractResolver.ResolveContract(objectType);
                try
                {
                    originalConverter = contract.Converter;
                    contract.Converter = null;
                    return serializer.Deserialize(reader2, objectType);
                }
                finally
                {
                    contract.Converter = originalConverter;
                }
            }
        }        
    }
}

编辑:

为内部循环使用全新的序列化程序似乎也可行,并且可以避免线程问题。这是一个合理的方法吗?

using (JTokenReader reader2 = new JTokenReader(nextToken))
{
    JsonSerializer tempSerializer = JsonSerializer.Create(new JsonSerializerSettings());
    tempSerializer.ContractResolver.ResolveContract(objectType).Converter = null;
    return tempSerializer.Deserialize(reader2, objectType);
}

0 个答案:

没有答案