我有一个自定义JsonConverter,我需要更改某些属性的默认序列化和反序列化。看看反序列化:
我正在覆盖ReadJson
方法,如下所示:
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName)
{
var propertyName = reader.Value.ToString();
if (reader.Read())
{
...
然后我可以检查TokenType,如果合适,可以自定义工作。这适用于大多数类型,但如果我有一个Enumerable属性并已被序列化为JsonArray,那么我想在继续我的自定义东西之前使用该属性的默认实现。
我该怎么做?
答案 0 :(得分:1)
当读者找到某个值时,您可以拨打JsonSerializer.Deserialize()
,JToken.Load()
,JArray.Load()
或JObject.Load()
来反序列化或加载该值。通常我更喜欢这样做来进行手动“原子”读取,因为它确保正确处理嵌套并使读者正确定位JSON流中的下一个项目。当定位在属性值上时,使用适当的类型调用JsonSerializer.Deserialize
将为您提供该属性的反序列化的默认实现。
实际上,编写ReadJson
方法的一种简单方法是将对象的全部内容加载到JObject
中,然后遍历属性:
var obj = JObject.Load(reader);
foreach (var property in obj.Properties())
{
switch (property.Name)
{
case "Data2":
{
// For example
myClass.Data2 = obj.ToObject<List<double>>(serializer);
}
break;
// More cases as necessary
default:
Debug.WriteLine("Unknown property " + property);
break;
}
}
如果出于某种原因你不想这样做,你可以阅读逐个属性并反序列化或加载单个值:
while (reader.Read() && reader.TokenType != JsonToken.EndObject)
{
if (reader.TokenType == JsonToken.PropertyName)
{
var propertyName = reader.Value.ToString();
if (reader.Read())
{
switch (propertyName)
{
case "Data1":
{
// Expecting a double value.
if (reader.TokenType == JsonToken.Integer || reader.TokenType == JsonToken.Float)
myClass.Data1 = Convert.ToDouble(reader.Value);
else
{
// Unknown value, skip or throw an exception
JToken.Load(reader);
}
}
break;
case "Data2":
{
// For example
myClass.Data2 = serializer.Deserialize<List<double>>(reader);
}
break;
case "Data3":
{
// Expecting a string value.
myClass.Data3 = JToken.Load(reader).ToString();
}
break;
default:
{
// Unknown property, skip or throw an exception
var unknownValue = JToken.Load(reader);
Debug.WriteLine(string.Format("Uknown property \"{0}\" with value: {1}", propertyName, unknownValue));
}
break;
}
}
}
}