2010-12-30 8 views
0

Es gibt ein Stück Zeichenfolge, die ich mit DataContractJsonSerializer deserialize möchte. Es gibt ein Mitglied in der JSON-Zeichenfolge, die manchmal ein Objekt oder eine Zeichenfolge sein kann. Wie so:DataContractJsonSerializer löst InvalidCastException für Member unterschiedlicher Typen aus

{ a: 1, b: 2, c: "c" } 

oder

{ a: 1, b: 2, c: {c1: 3, c2: 4} } 

Ich kenne die Struktur des Objekts im zweiten Fall (wir die Klasse nennen Inner), aber wie kann DataContractJsonSerializer konvertieren ein Objekt von zwei möglichen Arten?

Ich habe versucht, einen expliziten und impliziten Cast-Operator von string zu Inner zu konvertieren, aber es wird nicht getroffen. Ein InvalidCastException wird immer geworfen.

Antwort

0

Ich hatte eine ähnliche Situation, wo eine API entweder ein Array von Objekten zurückgab, oder nur das einzelne Objekt nicht in einem Array, wenn es nur ein Ergebnis gab. Ich war vollständig nicht in der Lage, den DataContractJsonSerializer dazu zu bringen. Ich musste schließlich in die JSON.NET-Bibliothek wechseln und mit JsonConverter ein wenig herumspielen, um es zum Laufen zu bringen.

In Ihrem DataContract deklarieren Sie 'c' als Typ Inner.

[DataMember(Name = "c")] 
public Inner C { get; set; } 

schreiben Sie dann eine JsonConverter den Token-Typ zu prüfen und das Richtige tun, wenn der Deserializer eine innere zu deserialisieren versucht.

internal class StringOrInnerConverter : JsonConverter { 
    public override bool CanConvert(Type objectType) { 
     return objectType == typeof(Inner); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
     var ser = new JsonSerializer(); 

     if (reader.TokenType == JsonToken.StartObject) { 
      var inn = ser.Deserialize<Inner>(reader); 
      return inn; 
     } else if (reader.TokenType == JsonToken.String) { 
      var str = ser.Deserialize<string>(reader); 
      return (Inner)str; // Or however you want to convert string to Inner 
     } else { 
      return default(Inner); 
     } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { 
     throw new System.NotImplementedException(); 
    } 
} 
Verwandte Themen