2016-09-06 5 views
1

Ich habe folgendes json:Deserialize json Eigenschaft als bool oder Doppel

"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 
     }, 
} 

Und ich habe die folgende Klasse die json deserialisieren:

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

Und wenn der Wert von reduce_rate ein false ist Ich möchte einen 0.0 sonst den doppelten Wert setzen. Aber in der Set-Methode geht nie in die else.

Gibt es einen anderen Ansatz, um diese Situation zu lösen?

+1

Nun, der Wert von 'value' im Setter ist ein' double', also warum würdest du erwarten, * nicht * in der Lage zu sein, es zu parsen? Musst du unbedingt mit diesem JSON arbeiten? Eine Eigenschaft zu haben, die entweder ein doppelter oder boolescher Wert sein kann, erscheint mir * schrecklich *. Sie können es am einfachsten finden, einen zweistufigen Prozess zu haben, in dem Sie dies zuerst in vernünftiges JSON konvertieren. Nebenbei empfehlen wir dringend, dass Sie den .NET-Benennungskonventionen für Ihre Eigenschaften folgen und Attribute verwenden, um anzugeben, wie sie in JSON serialisiert werden. –

+0

Die JSON-Quelle von https://euvatrates.com/rates.json. Ich kann die JSON –

+0

nicht ändern, tut es schon, was Sie wollen. Wenn Sie es testen wollen, können Sie unite test schreiben und die mock json Daten übergeben, anstatt sie von der eigentlichen Quelle zu bekommen. – CarbineCoder

Antwort

3

Eine Möglichkeit, dies zu handhaben, wäre, reduced_rate_alt als eine Zeichenfolge zu definieren und dann eine neue Eigenschaft zu definieren, die liest und versucht, das auf einen Wert im Getter zu analysieren. Das kann funktionieren, aber Sie haben mehr so ​​und da mit JSON.NET, der gleichen Wandler soll mit allen von ihnen arbeiten, würde ich manuell diese Eigenschaften konvertieren:

[JsonConverter(typeof(RateJsonConverter))] 
public decimal reduced_rate_alt { get; set; } 

jede der Eigenschaften Schmücken, die falsch könnten zurückkehren mit diesem Attribut. Dies teilt JSON.NET mit, dass Sie den Code zum Deserialisieren dieser Eigenschaft bereitstellen. Während Sie daran sind, können Sie auch die Eigenschaftsnamen mit [JsonProperty] beheben.

Die Regel/Konvertierung implementiert ist einfach 0 für false anderen Wert verwenden. Solange die Konvertierungsregel für alle gleich ist, können Sie für jede Eigenschaft den gleichen Konverter verwenden. Ich habe auch den Typ in Dezimal geändert, was wahrscheinlich für diese besser geeignet ist.

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

Ausgang für die ersten paar:

Schlüssel: AT (Österreich), reduziert alt Preis: 13.00
Schlüssel: BE (Belgien), reduziert alt rate: 6.00
Schlüssel: BG (Bulgarien), reduzierte Alter Rate: 0.00
Schlüssel: CY (Zypern), reduzierte Alter Rate: 5.00
Schlüssel: CZ (Tschechische Republik), reduziert alt Preis: 10.00
Schlüssel: DK (Dänemark), reduziert alt Preis: 0,00

BG und DK falsch sind und wandeln auf 0, während die anderen die haben Rate in der JSON aufgeführt.