Fabio Santos Fabio Santos - 11 months ago 49
JSON Question

C# deserialize json bool or a double

I have the following json:

"rates": {
"AT": {
"country": "Austria",
"standard_rate": 20.00,
"reduced_rate": 10.00,
"reduced_rate_alt": 13.00,
"super_reduced_rate": false,
"parking_rate": 12.00
"DK": {
"country": "Denmark",
"standard_rate": 25.00,
"reduced_rate": false,
"reduced_rate_alt": false,
"super_reduced_rate": false,
"parking_rate": false

And I have the following class to deserialize the json:

public string country { get; set; }
public double standard_rate { get; set; }
//public string reduced_rate { get; set; }
private double _reduced_rate;

public double reduced_rate
get { return _reduced_rate; }
bool isDouble = Double.TryParse(value.ToString(), out _reduced_rate);
if (isDouble)
_reduced_rate = value;
_reduced_rate = 0.0;

public string reduced_rate_alt { get; set; }
public string super_reduced_rate { get; set; }
public string parking_rate { get; set; }

And when the value of
is a
I want to set a
else the double value. But in the set method never enters into the

Is there another approach to resolve this situation?

Answer Source

One way to handle this would be to define reduced_rate_alt as a string and then define a new property which reads and tries to parse that to a value in the getter. That can work but you have several like that and since using JSON.NET, the same converter should work with all of them, I'd manually convert those properties:

public decimal reduced_rate_alt { get; set; }

Adorn each of the properties which might return false with that attribute. This tells JSON.NET that you are supplying the code to deserialize this property. While you are at it you may want to also fix up the property names with [JsonProperty].

The rule/conversion implements is simply to use 0 for false otherwise the value. As long as the conversion rule is the same for all of them, you can use the same converter for each property. I also changed the type to decimal which is probably more appropriate for these.

public class RateJsonConverter : JsonConverter
    public override bool CanConvert(Type objectType)
    {   // name used in a previous answer
        return (objectType == typeof(VRate));

    public override object ReadJson(JsonReader reader, Type objectType, 
                                object existingValue, JsonSerializer serializer)
        var token = JToken.Load(reader);
        decimal d = 0M;

        Decimal.TryParse(token.ToString(), out d);        
        return d;

    public override void WriteJson(JsonWriter writer, object value,
                    JsonSerializer serializer)
        throw new NotImplementedException();


var rates = JsonConvert.DeserializeObject<VRates>(jstr).rates;

foreach (KeyValuePair<string, VRate> kvp in rates)
    Console.WriteLine("key: {0} ({1}), reduced alt rate: {2}", kvp.Key, 
    kvp.Value.VTag = kvp.Key;

Output for the first few:

key: AT (Austria), reduced alt rate: 13.00
key: BE (Belgium), reduced alt rate: 6.00
key: BG (Bulgaria), reduced alt rate: 0.00
key: CY (Cyprus), reduced alt rate: 5.00
key: CZ (Czech Republic), reduced alt rate: 10.00
key: DK (Denmark), reduced alt rate: 0.00

BG and DK are false and convert to 0, while the others have the rate listed in the JSON.