2017-05-16 3 views
0

Ich habe eine Multiple-Level-Klasse (VPC/Subnetz/Instanz). Sie sind 1 zu viele Beziehung.JSON.NET Serialize Nested Complex Dictionary-Objekt

  • ein VPC könnte mehrere Subnetze haben.
  • ein Subnetz könnte mehrere Instanz

hat Jedes Objekt ist eine eigenständige Klasse und ich bin ein Wörterbuch halten Kind-Objekte verwenden. Also das Wörterbuch ist Dictionary <string, child object>.

Das untergeordnete Objekt könnte verschiedene Typen haben, aber alle aus derselben Basisklasse. Ich verwende Generika in der Klasse. Hier

ist der Code für die VPC-Klasse:

public class CEVpcBase : CECloudVpcBase 
{ 
    [JsonProperty("CESubnetCache")] 
    public CESubnetCache CESubnetCache { get; set; } 
    public CESnapshotCache CESnapshotCache { get; set; } 
    public List<CEVpcGroup> CEVpcGroups { get; set; } 
    public BrokerAuthenticationBase BrokerAuthentication; 
    protected DynamoDBHelper dynamoDbHelper; 

    public CEVpcBase(DynamoDBHelper dynamoDbHelper) 
    { 
     this.dynamoDbHelper = dynamoDbHelper; 
     //we can's init subnet/snapshot cache here because, we need the cloud account 
     //the cloud account is not init until the base class init 
     this.CEVpcGroups = new List<CEVpcGroup>(); 
    } 
... 
} 

Hier ist der Code für das Kind Objekt:

public class CESubnetCache : CECacheBase<CESubnetBase> 
{ 
    [JsonIgnore] 
    public CEVpcBase ParentVpc { get; } 
    [JsonConstructor] 
    public CESubnetCache() 
    { 

    } 
    public CESubnetCache(CEVpcBase vpc, DynamoDBHelper dbHelper) : base(dbHelper) 
    { 
     this.ParentVpc = vpc; 
     this.ec2Client = CloudClientFactory.GetCloudClient(ParentVpc.CloudAccount, CloudClientType.AwsEC2) as AmazonEC2Client; 
     this.CreatedOn = DateTime.Now; 
     log.InfoFormat("ParentVpc:{0}**{1} subnet cache created", ParentVpc.ObjectId, ParentVpc.ObjectName); 
    } 
} 

Das Wörterbuch ist in der Basisklasse.

[JsonObject(MemberSerialization.OptIn)] 
public abstract class CECacheBase<T> 
{ 
    [JsonIgnore] 
    protected AmazonEC2Client ec2Client; 
    [JsonIgnore] 
    protected log4net.ILog log = log4net.LogManager.GetLogger(typeof(CECacheBase<T>)); 
    protected ConcurrentDictionary<string, T> items = new ConcurrentDictionary<string, T>(); 
    protected DateTime CreatedOn; 
    protected DateTime UpdatedOn; 
    public string test = "test"; 
    public virtual async Task Load() { } 
    public virtual async Task Load(object o) { } 
    public virtual async Task<ConcurrentDictionary<string, T>> Load(string id, string name) { return null; } 
    protected bool isInitialized = false; 
    protected object lockObject = new object(); 
    [JsonIgnore] 
    protected DynamoDBHelper dynamoDBhandler; 
    [JsonConstructor] 
    public CECacheBase() 
    { 

    } 
} 

Und hier ist der Code für CESubnetBase:

public class CESubnetBase : CECloudSubnetBase 
{ 
    [JsonIgnore] 
    public CEVpcBase ParentVpc { get; set; } 
    [JsonProperty("CEInstanceCache")] 
    public CEInstanceCache CEInstanceCache { get; set; } 
    [JsonConstructor] 
    public CESubnetBase() 
    { 

    } 
} 

ich alle verschiedenen Arten von json.net Attribute versucht haben. Aber in der serialisierten JSON-Datei zeigt CESubnetCache als ein leeres Objekt {}. In meinem Code, der oben gezeigt wird, hat die CESubnetCache Klasse ein items Wörterbuch. Ich erwartete, dass das Wörterbuch serialisiert werden würde.

"vpc-68c3090c": { 
"BrokerAuthentication": null, 
"CESubnetCache": {}, 
"CESnapshotCache": {}, 
"CEVpcGroups": [], 
"VpcCidr": "10.1.0.0/16", 
"InstanceStatic": null, 
"StackId": "arn:aws-cn:cloudformation:cn-north-1:663242140710:stack/MYCloud-2017-3-18-10-28-6/93f37bc0-0bc5-11e7-8d6d-50fa18a0d262", 
"StackName": "MYCloud-2017-3-18-10-28-6", 
"AdNatStatus": null, 
"StackStatus": null, 
"VpcSummary": { 
    "LanSgId": null, 
    "DmzSgId": null, 
    "GatewayIP": "54.223.239.78", 
    "ADInstanceId": "i-0be9a18f05927dea2", 
    "VpcType": null, 
    "AuthenticationType": "AD", 
    "DomainName": "MYCloud.local", 
    "IsSoftDeleted": false 
}, 
"VpcMetadata": { 
    "CloudAccountId": "AWS-663242140710-CNNorth1", 
    "VpcDns": "MYCloud", 
    "AdAmiId": null, 
    "NatAmiId": null 
}, 

Hier ist, wie ich es serialisiert:

var json = JsonConvert.SerializeObject(input, Formatting.Indented); 

Was kann ich tun Json.Net bekomme das Wörterbuch serialisieren?

+0

* "Aber meine Serialisierung speichert das Kindobjekt nicht." * Auf welches Kindobjekt beziehen Sie sich? Was ist dein erwartetes Ergebnis? –

+0

Das untergeordnete Objekt, auf das ich verweise, ist "CESubnetCache": {} ,. Es wird in der serialisierten JSON-Datei als leer angezeigt. Ich habe es in meinem Post. Der CESubnetCache enthält ein Wörterbuch. protected ConcurrentDictionary items = new ConcurrentDictionary (); Was ich erwarte ist, dass es dieses Wörterbuch serialisieren sollte. –

+0

@Brian Rogers, Ich habe gestern gesehen, dass Sie eine Antwort gegeben haben, indem Sie JsonProperty zu meinem Wörterbuchobjekt hinzufügen, da es geschützt ist. Es klappt. Aber ich kann die Antwort heute nicht sehen. Ich bin ein Neuling für stackoverflow, könnte ich etwas falsch machen, um deine Antwort verschwinden zu lassen? –

Antwort

0

Von Ihren Kommentaren haben Sie gesagt, dass CESubnetCache als leeres Objekt serialisiert wird, und Sie erwartet, dass das Wörterbuch darin serialisiert würde. Der Grund, warum das Wörterbuch nicht serialisiert wird, liegt darin, dass die Basisklasse eine Opt-In-Semantik verwendet, wie durch das Attribut [JsonObject(MemberSerialization.OptIn)] angezeigt. Das bedeutet, dass keine Mitglieder dieser Klasse serialisiert werden, es sei denn, Sie kennzeichnen sie auch mit den Attributen [JsonProperty].

Try [JsonProperty("Items")] das Wörterbuch Mitglied hinzufügen, und dass das Problem lösen soll:

[JsonObject(MemberSerialization.OptIn)] 
public abstract class CECacheBase<T> 
{ 
    ... 
    [JsonProperty("Items")] 
    protected ConcurrentDictionary<string, T> items = new ConcurrentDictionary<string, T>(); 
    ... 
} 

Ich soll auch erwähnen, dass, wenn Sie aus der Klasse das [JsonObject(MemberSerialization.OptIn)] Attribut entfernen sind, das Wörterbuch noch würde in diesem Fall nicht ohne das Attribut [JsonProperty] serialisiert, da es protected statt public ist. Json.Net serialisiert nur öffentliche Mitglieder standardmäßig. In beiden Fällen benötigen Sie hier das Attribut [JsonProperty].

+0

Ja, JsonProperty hat das Problem gelöst –

Verwandte Themen