web-dev-qa-db-fra.com

Newtonsoft JSON - Comment utiliser la méthode JsonConverter.ReadJson pour convertir des types lors de la désérialisation de JSON

J'ai besoin d'aide pour comprendre comment utiliser la méthode JsonConverter.ReadJson pour convertir une valeur d'un nombre quelconque de types (chaîne, booléen, Date, int, tableau, objet) en un type personnalisé spécifique.

Par exemple, j'ai les éléments suivants:

    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);
    }

Mais cela donne une erreur.

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

Je suis un peu vert avec C #, j'ai juste besoin d'aide pour faire ce travail.

8
ClaraU

A finalement résolu le problème;

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;
}

Pas sûr que ce soit la meilleure solution possible, mais ça fait le travail.

15
ClaraU

Vous pouvez tester le type de valeur avant de convertir . Vous pouvez le faire comme ceci:

if (reader.TokenType != JsonToken.String)
{
    throw new JsonSerializationException();
}

var value = serializer.Deserialize<string>(reader);
3
Antoine Castiglione

Depuis sa base d'un objet, et vous voulez juste une chaîne, pourquoi ne pas l'appeler comme ceci:

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