Reputation: 253
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; }
set
{
bool isDouble = Double.TryParse(value.ToString(), out _reduced_rate);
if (isDouble)
_reduced_rate = value;
else
_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 reduce_rate
is a false
I want to set a 0.0
else the double value. But in the set method never enters into the else
.
Is there another approach to resolve this situation?
Upvotes: 1
Views: 5273
Reputation: 38905
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:
[JsonConverter(typeof(RateJsonConverter))]
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();
}
}
Testing:
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.country,
kvp.Value.reduced_rate_alt.ToString("F2"));
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.
Upvotes: 5