Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best practice to deserialize a JSON object with field that might be either string or int?

I am trying to use Newton Json Deserializer to deserialize json object which looks like this:

{
  "grades": 97
}

Or this:

{
  "grades": ""
}

I wonder how should I properly define a DTO class in C# to represent the this object? Thanks!

like image 993
Lifu Huang Avatar asked Oct 11 '25 09:10

Lifu Huang


2 Answers

Please try with dynamic keyword:

public class Rootobject
{
     public dynamic grades { get; set; }
}

It will work with both string and int. For more info refer to using dynamic type.

UPDATE:

Then to convert into int or string I will use Convert.ToString() because it handles null values and for int I will use Int32.TryParse() because I can better control conversion to int if input drades are not properly formatted.

UPDATE:

Any nullable type in C# will become null if grades are "". For that purpose, you can use int?. But if grades are something like "3ds" then you have to use some dynamic approach.

like image 130
kat1330 Avatar answered Oct 13 '25 23:10

kat1330


I would rather use a custom JsonConverter on your POCO, which would ensure that the object gets deserialized into one expected type, rather than using object or dynamic, and then having to treat that property with suspicion throughout your codebase.

Here's how I would do it:

public class IntConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value.GetType() == typeof(int))
            writer.WriteValue((int)value);
        else
            writer.WriteValue(value.ToString());
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => 
        ParseInt(reader.Value.ToString());

    public override bool CanConvert(Type objectType) =>
        objectType == typeof(int) || objectType == typeof(string);

    private static int ParseInt(string value)
    {
        int parsedInt = 0;
        int.TryParse(value, out parsedInt);
        return parsedInt;
    }
}

And then use this JsonConverter in your POCO like this:

public class Student
{
    [JsonProperty("grades"), 
    JsonConverter(typeof(IntConverter))]
    public int Grades;
}

I would find this is 'best practice' for these things.

like image 31
Andre Andersen Avatar answered Oct 13 '25 22:10

Andre Andersen