17

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.

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
ClaraU
  • 877
  • 3
  • 11
  • 22

3 Answers3

33

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.

Dima
  • 1,717
  • 15
  • 34
ClaraU
  • 877
  • 3
  • 11
  • 22
2

Since its basic of an object, and you just want string, why don't you call it like this:

 return new MyCustomType(reader.Value.ToString());
MoustafaS
  • 1,991
  • 11
  • 20
  • thanks MoustafaS that handles only one type (string), I need to be able to handle all types: string, boolean, date, int, array, object – ClaraU Jul 26 '16 at 11:07
  • You mentioned that you want to convert to string, how would you handle array ? all other objects implement .ToString() @claracruz – MoustafaS Jul 26 '16 at 11:14
  • A string is just one example, but that's my question how do I handle all datatypes – ClaraU Jul 26 '16 at 12:28
2

You can test the value type before to convert. You can do that like this :

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

var value = serializer.Deserialize<string>(reader);
  • 5
    This method causes a stack overflow for me since Deserialize(reader) causes ReadJson to be called again. – Joshcodes Nov 13 '18 at 19:14