Search code examples
c#json.netjson-deserialization

Newtonsoft JSON - How to use the JsonConverter.ReadJson method to convert types when deserializing JSON


I need help understanding how to use the the JsonConverter.ReadJson method to convert a value of any number of types (string, boolean, Date, int, array, object) to a specific custom type.

For example, I have the following;

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

But this gives error;

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

I'm a bit green with C#, just need help making this work.


Solution

  • Finally worked it out;

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

    Not sure if this is the best possible solution, but it does the job.