2016-07-22 7 views
1

Angenommen, wir haben die folgenden KlassendefinitionenSerialize komplexe Eigenschaft des Objekts als Skalarwert

public class A 
{ 
    public string Name { get; } = "Johny Bravo"; 
    public B ComplexProperty { get; } = new B(); 
} 

public class B 
{ 
    public string Prop1 { get; } = "value1"; 
    public string Prop2 { get; } = "value2"; 
    public int Prop3 { get; } = 100; 

    public override string ToString() 
    { 
     return this.Prop3.ToString(); 
    } 
} 

wenn serialisierte

var a = new A(); 
var str = JsonConvert.SerializeObject(a); 

es in dem folgenden JSON-String

{ 
    "Name":"Johny Bravo", 
    "ComplexProperty":{ 
     "Prop1":"value1", 
     "Prop2":"value2", 
     "Prop3":100 
    } 
} 

führen Wie machen wir die ComplexProperty serialize als skalaren Wert? Das gewünschte Ergebnis muss diese:

{ 
    "Name":"Johny Bravo", 
    "ComplexProperty":100 
} 

Antwort

2

Die richtige Lösung für dieses Problem ist eine benutzerdefinierte JsonConverter verwenden, die Ihren Typ verarbeiten kann. Vor allem, wenn Sie keine Kontrolle über den Code von A- und B-Klassen haben. Hier ist der Beispielcode

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var a = new A(); 
      var str = JsonConvert.SerializeObject(a, new JsonSerializerSettings() 
      { 
       Converters = new List<JsonConverter>() 
       { 
        new BTypeJsonConverter() 
       } 
      }); 
     } 
    } 

    public class A 
    { 
     public string Name { get; } = "Johny Bravo"; 
     public B ComplexProperty { get; } = new B(); 
    } 

    public class B 
    { 
     public string Prop1 { get; } = "value1"; 
     public string Prop2 { get; } = "value2"; 
     public int Prop3 { get; } = 100; 

     public override string ToString() 
     { 
      return this.Prop3.ToString(); 
     } 
    } 

    public class BTypeJsonConverter : JsonConverter 
    { 
     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      var b = value as B; 
      if (b == null) return; 
      writer.WriteValue(b.ToString()); 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, 
      JsonSerializer serializer) 
     { 
      throw new NotImplementedException(); 
     } 

     public override bool CanConvert(Type objectType) 
     { 
      return objectType == typeof(B); 
     } 
    } 
} 
3

Ihr Code wird nicht kompiliert werden, weil Sie eine B-Klasse zuweisen Wert auf int Aber ich glaube, ich bekommen, was Sie wollen:

class Program 
    { 


    static void Main(string[] args) 
    { 
     var a = new A(); 
     var str = JsonConvert.SerializeObject(a); 
     Console.Write(str); 
    } 
} 

public class A 
{ 
    public string Name { get; } = "Johny Bravo"; 
    [JsonIgnore] 
    public B ComplexProperty { get; } = new B(); 
    [JsonProperty("ComplexProperty")] 
    public int complexValue => ComplexProperty.Prop3; 
} 

public class B 
{ 
    public string Prop1 { get; } = "value1"; 
    public string Prop2 { get; } = "value2"; 
    public int Prop3 { get; } = 100; 

    public override string ToString() 
    { 
     return this.Prop3.ToString(); 
    } 
} 

Da Sie wollen Wenn Ihr Objekt flach ist (nur 1 Ebenentiefe), müssen Sie die Eigenschaft auf Ihrer A-Klasse haben. Da Sie Ihr komplexes Objekt nicht im json-Ergebnis haben möchten, müssen Sie es ignorieren, und da Sie für die Json-Ergebnisse denselben Namen haben müssen, müssen Sie dem json-Serializer mitteilen, dass Ihre Daten mit den erforderlichen Daten serialisiert werden sollen Name

+0

Danke für Ihre Antwort. Ich habe an so etwas gedacht, aber was ist, wenn A und B aus einer 3rd-Party-Bibliothek kommen? –

+0

@MihailShishkov macht es keinen Unterschied. Sie haben die Methode get, so dass Sie den gewünschten Wert haben können. wie public int complexValue => SomeMethod (someObjects); –

+0

Wenn Sie A und B in einer Drittanbieter-Bibliothek haben, können Sie ihren Code nicht ändern. Sie können also nicht einfach neue Attribute oder Eigenschaften hinzufügen. Ihr Vorschlag wird funktionieren, wenn ich nur um die Serialisierung herum einen Adapter für A anbiete, was mir sehr viel Arbeit bedeutet. Stellen Sie sich vor, wenn A eine echte Klasse mit vielen Eigenschaften ist :) –

0

eine andere Eigenschaft hinzufügen und die Serialisierung PropertyName zunächst eins gesetzt. Wenn Ihre Klasse A von einer Drittanbieterbibliothek stammt, erstellen Sie eine Klasse, die von A abgeleitet ist, und fügen Sie die neue Eigenschaft hinzu.

public class A 
{ 
    public string Name { get; } = "Johny Bravo"; 
--> [JsonIgnore] 
    public B ComplexProperty { get; } = new B(); 
-->[JsonProperty(PropertyName = "ComplexProperty")] 
--> public string ComplexPropertyText { get{ return ComplexProperty.ToString(); } } 
} 

public class B 
{ 
    public string Prop1 { get; } = "value1"; 
    public string Prop2 { get; } = "value2"; 
    public int Prop3 { get; } = 100; 

    public override string ToString() 
    { 
     return this.Prop3.ToString(); 
    } 
} 
Verwandte Themen