2016-04-15 13 views
0

Ich habe ein flaches Objekt, das ich in Abschnitte gruppieren möchte, um das Parsen einfacher zu machen. Dies ist die grundlegende Idee von dem, was meine Klasse derzeit wie folgt aussieht:So gruppieren Sie Eigenschaften beim Serialisieren zu JSON

class Populations { 
    public string US { get; set; } 
    public string Canada { get; set; } 

    public string Germany { get; set; } 
    public string England { get; set; } 
} 

Aber das ist, was ich will es in serialisiert werden, wenn sie mit Daten gefüllt:

{ 
    "Populations": { 
    "North America": { 
     "US": "318 million", 
     "Canada": "35 million" 
    }, 
    "Europe": { 
     "Germany": "80 million", 
     "England": "53 million" 
    } 
    } 
} 

Was ich versuche zu tun, wickle meine Länder in Kontinente ein, ohne tatsächlich neue Kontinentalklassen zu schaffen. Ist das mit einem Tool wie Json.Net möglich oder muss ich einfach eine NorthAmerica Klasse mit zwei Eigenschaften erstellen und dann eine Europe Klasse mit zwei Eigenschaften erstellen? Ist es möglich, dass eine Annotation existiert, um einige dieser Eigenschaften zusammenzufassen?

+1

'wickle meine Länder in Kontinente ein 'Wo ist die Kartenfunktion dafür .... – Eser

+0

Verwenden Sie ein Array von Klassen 'Country' mit den Eigenschaften' Name', 'Population' und' Kontinent'. – abatishchev

Antwort

1

könnten Sie Klassen erstellen NorthAmerica und Europe, oder man könnte so etwas wie tun:

class Continent{ 
    string Type { get; set; } 
    ICollection<Country> Countries { get; set; } 
} 

Dies würde natürlich notwendig, dass alle Länder haben eine gemeinsame Basisklasse oder Schnittstelle.

+0

Würde das nicht in etwas etwas anderes als das json, das er will, serialisieren? Sein JSON scheint zu implizieren, dass er will, dass NorthAmerica Eigenschaften von US und Kanada hat. Die Continent-Klasse, die Sie vorschlagen, würde sie zu einem Array machen, wenn sie serialisiert werden, oder? –

+0

@JaredDrake Es ist anders als das JSON, aber er sagte auch "das ist, was ich versuche zu tun". Weder erreicht er sein Ziel direkt, aber ... –

+0

Ya, ich verstehe was du meinst. Er wird seinen JSON geben oder Kurse machen/modifizieren müssen. –

0

Da Ihre JSON keine Arrays enthält, können Sie mit aktuellen Klassen diese JSON nicht erstellen, es sei denn, Sie erstellen eine andere Klasse mit der gewünschten Struktur oder wählen sie in ein dynamisches Objekt aus.

Wenn Sie sich strikt an diese JSON halten müssen, möchte ich Sie ermutigen, eine andere Bevölkerungs Klasse zu machen, die eine Struktur wie

class Populations { 
    public NorthAmerica NorthAmerica { get; set; } 
    public Europe Europe { get; set; } 
} 

class NorthAmerica{ 
    public string US { get; set; } 
    public string Canada { get; set; } 
} 

class Europe{ 
    public string Germany{ get; set; } 
    public string England{ get; set; } 
} 
+0

Sind Sie sich über die Eigenschaften von 'Populationen' sicher? 'Germany' oder' Europe' – Eser

+0

@Eser Fixed it. Vielen Dank! –

0

hat Es gibt keinen eingebauten Mechanismus in Json.Net diese Gruppierung zu tun wie du beschreibst; Sie können jedoch eine benutzerdefinierte JsonConverter machen, wenn dies das ist, was Sie wirklich wollen. So etwas wie dies funktionieren könnte:

class GroupAttribute : Attribute 
{ 
    public string Name { get; set; } 
    public GroupAttribute(string name) 
    { 
     Name = name; 
    } 
} 

class GroupingConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     JObject obj = new JObject(); 
     Type type = value.GetType(); 
     foreach (PropertyInfo pi in type.GetProperties()) 
     { 
      JToken propVal = JToken.FromObject(pi.GetValue(value)); 
      GroupAttribute group = pi.GetCustomAttribute<GroupAttribute>(); 
      if (group != null) 
      { 
       JObject groupObj = (JObject)obj[group.Name]; 
       if (groupObj == null) 
       { 
        groupObj = new JObject(); 
        obj.Add(group.Name, groupObj); 
       } 
       groupObj.Add(pi.Name, propVal); 
      } 
      else 
      { 
       obj.Add(pi.Name, propVal); 
      } 
     } 

     JObject wrapper = new JObject(new JProperty(type.Name, obj)); 
     wrapper.WriteTo(writer); 
    } 

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

    public override bool CanRead 
    { 
     get { return false; } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     // CanConvert is not called when a [JsonConverter] attribute is applied 
     return false; 
    } 
} 

Sie würden dann markieren Sie Ihre Populations Klasse wie folgt:

[JsonConverter(typeof(GroupingConverter))] 
class Populations 
{ 
    [Group("North America")] 
    public string US { get; set; } 
    [Group("North America")] 
    public string Canada { get; set; } 

    [Group("Europe")] 
    public string Germany { get; set; } 
    [Group("Europe")] 
    public string England { get; set; } 
} 

Schließlich Serialisierung wie folgt aus:

string json = JsonConvert.SerializeObject(populations, Formatting.Indented); 

Fiddle: https://dotnetfiddle.net/EPiJue

Verwandte Themen