2017-05-16 13 views
0

私は複数レベルのクラス(vpc /サブネット/インスタンス)を持っています。彼らは1対多の関係です。JSON.NETネストされた複合ディクショナリオブジェクトをシリアライズ

  • 1つのvpcに複数のサブネットが存在する可能性があります。
  • 1のサブネットは、すべてのオブジェクトがスタンドアロンクラスであると私は辞書ホールド子オブジェクトを使用しています複数のインスタンスに

を持つことができます。したがって、辞書はDictionary <string, child object>です。

子オブジェクトは異なるタイプである可能性がありますが、それらはすべて同じ基本クラスのものです。私はクラスでジェネリック薬を使用しています。ここで

はVPCクラスのコードです:ここで

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>(); 
    } 
... 
} 

は、子オブジェクトのコードです:

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

辞書は、基本クラスです。

[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() 
    { 

    } 
} 

そして、ここではCESubnetBaseのコードです:

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

    } 
} 

私はjson.net属性のすべての種類を試してみました。しかし、シリアライズされたjsonファイルでは、は空のオブジェクトとして表示されます{}。上記の私のコードでは、CESubnetCacheクラスはitemsの辞書を持っています。私は辞書が連載されることを期待しました。ここで

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

は、私はそれをシリアル化する方法である:

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

私はJson.Net辞書をシリアル化するために取得するために何ができますか?

+0

* "私のシリアライゼーションは子オブジェクトを保存しません" *どの子オブジェクトを参照していますか?さらに、あなたの期待している結果は何ですか? –

+0

私が参照する子オブジェクトは "CESubnetCache"です:{} ,.シリアライズされたjsonファイルでは空と表示されます。私は私のポストでそれを持っています。 CESubnetCacheには辞書があります。保護されたConcurrentDictionary アイテム=新しいConcurrentDictionary ();私が期待しているのは、その辞書をシリアライズする必要があるということです。 –

+0

@Brian Rogers、昨日、辞書オブジェクトに保護されているJsonPropertyを追加する答えを出しました。できます。しかし、私は今日答えを見ることができません。私はあなたの答えが消えたように間違ってsthを行うことができますか? –

答えて

0

あなたのコメントから、CESubnetCacheは空のオブジェクトとしてシリアライズされており、その中の辞書はシリアル化されると予想しました。辞書がシリアル化されない理由は、基底クラスが[JsonObject(MemberSerialization.OptIn)]属性で示されているオプトインセマンティクスを使用しているためです。つまり、そのクラスのメンバは、[JsonProperty]という属性も付けない限り、そのクラスのメンバはシリアル化されません。

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

私はまた、あなたがにした場合、クラスから[JsonObject(MemberSerialization.OptIn)]属性、辞書まだを削除することを言及する必要があります:辞書メンバーに[JsonProperty("Items")]を追加し、それが問題を解決する必要があり

てみてくださいこの場合[JsonProperty]属性なしではシリアル化されません。これはpublicではなくprotectedであるためです。 Json.Netはデフォルトでパブリックメンバーのみをシリアル化します。だからいずれにしても、[JsonProperty]属性が必要です。

+0

はい、JsonPropertyが問題を解決しました –

関連する問題