【问题标题】:Newtonsoft JSON - How to use the JsonConverter.ReadJson method to convert types when deserializing JSONNewtonsoft JSON - 如何在反序列化 JSON 时使用 JsonConverter.ReadJson 方法转换类型
【发布时间】:2016-11-29 21:59:27
【问题描述】:

我需要帮助了解如何使用 JsonConverter.ReadJson 方法将任意数量类型(字符串、布尔值、日期、整数、数组、对象)的值转换为特定的自定义类型。

例如,我有以下;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {   
       //where reader.Value could be a string, boolean, Date, int, array, object
       //and in this example the value of reader.Value is a string
        return new MyCustomType(reader.Value);
    }

但这会产生错误;

Compilation error (line 115, col 36): Argument 1: cannot convert from 'object' to 'string'

我对 C# 有点陌生,只是需要帮助来完成这项工作。

【问题讨论】:

    标签: c# json.net json-deserialization


    【解决方案1】:

    既然它是一个对象的基础,而你只想要字符串,你为什么不这样称呼它:

     return new MyCustomType(reader.Value.ToString());
    

    【讨论】:

    • 感谢 MoustafaS 只处理一种类型(字符串),我需要能够处理所有类型:字符串、布尔值、日期、整数、数组、对象
    • 您提到要转换为字符串,您将如何处理数组?所有其他对象实现 .ToString() @claracruz
    • 字符串只是一个例子,但我的问题是如何处理所有数据类型
    【解决方案2】:

    您可以在转换之前测试值类型。 你可以这样做:

    if (reader.TokenType != JsonToken.String)
    {
        throw new JsonSerializationException();
    }
    
    var value = serializer.Deserialize<string>(reader);
    

    【讨论】:

    • 这个方法会导致堆栈溢出,因为 Deserialize(reader) 会导致 ReadJson 再次被调用。
    【解决方案3】:

    终于搞定了;

    public override object ReadJson(
        JsonReader reader,
        Type objectType, 
        object existingValue, 
        JsonSerializer serializer)
    {
        MyCustomType myCustomType = new MyCustomType();//for null values        
    
        if (reader.TokenType != JsonToken.Null)
        {           
            if (reader.TokenType == JsonToken.StartArray)
            {
                JToken token = JToken.Load(reader); 
                List<string> items = token.ToObject<List<string>>();  
                myCustomType = new MyCustomType(items);
            }
            else
            {
                JValue jValue = new JValue(reader.Value);
                switch (reader.TokenType)
                {
                    case JsonToken.String:
                        myCustomType = new MyCustomType((string)jValue);
                        break;
                    case JsonToken.Date:
                        myCustomType = new MyCustomType((DateTime)jValue);
                        break;
                    case JsonToken.Boolean:
                        myCustomType = new MyCustomType((bool)jValue);
                        break;
                    case JsonToken.Integer:
                        int i = (int)jValue;
                        myCustomType = new MyCustomType(i);
                        break;
                    default:
                        Console.WriteLine("Default case");
                        Console.WriteLine(reader.TokenType.ToString());
                        break;
                }
            }
        }      
        return myCustomType;
    }
    

    不确定这是否是最好的解决方案,但确实可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多