我的类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); 导致无限递归。
这可以轻易地完成吗? (无需手动逐个属性)
答案 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。