自定义 JsonConverter - 恢复为数组属性的默认实现
Custom JsonConverter - revert to default implemetation for array properties
我有一个自定义的 JsonConverter,我需要在其中更改某些属性的默认序列化和反序列化。查看反序列化:
我正在覆盖 ReadJson
方法,如下所示:
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName)
{
var propertyName = reader.Value.ToString();
if (reader.Read())
{
...
然后我可以检查 TokenType,如果合适的话,做我的自定义工作。这适用于大多数类型,但如果我有一个 属性 是可枚举的并且已序列化为 JsonArray 那么我想在继续我的自定义内容之前使用该 属性 的默认实现。
我该怎么做?
当reader定位到一个值时,可以调用JsonSerializer.Deserialize()
, JToken.Load()
, JArray.Load()
or JObject.Load()
反序列化或加载该值。通常我更喜欢这样做而不是手动读取 "atomic",因为它确保正确处理嵌套并使 reader 正确定位到 JSON 流中的下一个项目。当位于 属性 值上时,使用适当的类型调用 JsonSerializer.Deserialize
将为您提供该 属性.
的默认反序列化实现
其实简单的写一个ReadJson
method is to load the entire contents of the object into a 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;
}
}
如果出于某种原因您不想这样做,您可以阅读 属性-by-属性 并反序列化或加载单个值:
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;
}
}
}
}
我有一个自定义的 JsonConverter,我需要在其中更改某些属性的默认序列化和反序列化。查看反序列化:
我正在覆盖 ReadJson
方法,如下所示:
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName)
{
var propertyName = reader.Value.ToString();
if (reader.Read())
{
...
然后我可以检查 TokenType,如果合适的话,做我的自定义工作。这适用于大多数类型,但如果我有一个 属性 是可枚举的并且已序列化为 JsonArray 那么我想在继续我的自定义内容之前使用该 属性 的默认实现。
我该怎么做?
当reader定位到一个值时,可以调用JsonSerializer.Deserialize()
, JToken.Load()
, JArray.Load()
or JObject.Load()
反序列化或加载该值。通常我更喜欢这样做而不是手动读取 "atomic",因为它确保正确处理嵌套并使 reader 正确定位到 JSON 流中的下一个项目。当位于 属性 值上时,使用适当的类型调用 JsonSerializer.Deserialize
将为您提供该 属性.
其实简单的写一个ReadJson
method is to load the entire contents of the object into a 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;
}
}
如果出于某种原因您不想这样做,您可以阅读 属性-by-属性 并反序列化或加载单个值:
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;
}
}
}
}