我有一个多级别的类(vpc / subnet / instance)。他们是一对多的关系。
每个对象都是一个独立的类,我使用字典保持子对象。所以字典是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
显示为空对象{}
。在我的代码中,如上所示,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
被序列化为一个空对象,你期望它里面的字典会被序列化。字典未被序列化的原因是因为基类使用了opt-in语义,如其上的[JsonObject(MemberSerialization.OptIn)]
属性所示。这意味着除非您使用[JsonProperty]
属性标记它们,否则不会序列化该类的任何成员。
尝试将[JsonProperty("Items")]
添加到字典成员中,这应解决问题:
[JsonObject(MemberSerialization.OptIn)]
public abstract class CECacheBase<T>
{
...
[JsonProperty("Items")]
protected ConcurrentDictionary<string, T> items = new ConcurrentDictionary<string, T>();
...
}
我还应该提一下,如果您要从类中删除 [JsonObject(MemberSerialization.OptIn)]
属性,那么在没有{{1}的情况下,字典仍然将无法序列化在这种情况下属性,因为它是[JsonProperty]
而不是protected
。 Json.Net默认只序列化公共成员。因此,无论哪种方式,您都需要public
属性。