使用JsonConverter进行Json.NET自定义序列化 - 如何获取“默认”行为

时间:2016-02-23 19:57:32

标签: c# json serialization json.net

我的类DataType有一个JsonConverter。 当Json中使用的普通字符串作为DataType类型的属性值时,我想做一些特殊处理。在值是“完整”对象的情况下,我想进行“正常”反序列化。

这是我的尝试

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.Value != null && reader.ValueType == typeof (string))
    {
        return someSpecialDataTypeInstance;
    }
    else if (reader.TokenType == JsonToken.StartObject)
    {
        DataType dataType = serializer.Deserialize<DataType>(reader);
        return dataType;
    }
    else
    {
        throw new JsonSerializationException();
    }
}

但这不起作用,因为这行: DataType dataType = serializer.Deserialize(reader); 导致无限递归。

这可以轻易地完成吗? (无需手动逐个属性)

1 个答案:

答案 0 :(得分:7)

一种简单的方法是分配一个类的实例,然后使用JsonSerializer.Populate(JsonReader, Object)。这是在标准CustomCreationConverter<T>中完成的方式:

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value != null && reader.ValueType == typeof(string))
        {
            return someSpecialDataTypeInstance;
        }
        else if (reader.TokenType == JsonToken.StartObject)
        {
            existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
            serializer.Populate(reader, existingValue);
            return existingValue;
        }
        else if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }
        else
        {
            throw new JsonSerializationException();
        }
    }

请注意,这不会处理启用TypeNameHandling并且存在指定多态子类型的"$type"属性的情况。在这种情况下,您需要执行JsonConverter with Interface中更新的JsonDerivedTypeConverer<T>的一些技巧。这也假设该类型具有Json.NET可访问的parameterless constructor。如果没有,并且existingValue为空,则需要通过new DataType(arg1, arg2, ...)手动构建它。

示例fiddle