自定义 JsonConverter语言 - 恢复为数组属性的默认实现



我有一个自定义的 JsonConverter,我需要在其中更改某些属性的默认序列化和反序列化。查看反序列化:

我正在覆盖ReadJson方法,如下所示:

while (reader.Read())
{
    if (reader.TokenType == JsonToken.PropertyName)
    {
        var propertyName = reader.Value.ToString();
        if (reader.Read())
        {
            ...

然后,我可以检查令牌类型,并在适当的情况下执行我的自定义工作。这适用于大多数类型,但是如果我有一个可枚举的属性并且已序列化为 JsonArray,那么我想在继续我的自定义内容之前使用该属性的默认实现。

我该怎么做?

当读取器位于某个值时,您可以调用 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;
                    }
                }
            }
        }

相关内容

  • 没有找到相关文章

最新更新