因为我最近遇到了类似的问题,所以我想我会把我的帽子扔在戒指上。这是我想反序列化的 JSON 示例:
{
"agencyId": "agency1",
"overrides": {
"assumption.discount.rates": "value: 0.07",
".plan": {
"plan1": {
"assumption.payroll.growth": "value: 0.03",
"provision.eeContrib.rate": "value: 0.35"
},
"plan2": {
".classAndTier": {
"misc:tier1": {
"provision.eeContrib.rate": "value: 0.4"
},
"misc:tier2": {
"provision.eeContrib.rate": "value: 0.375"
}
}
}
}
}
}
这适用于覆盖在不同级别应用并沿树继承的系统。无论如何,我想要的数据模型可以让我拥有一个带有这些特殊继承规则的属性包。
我最终得到的是以下内容:
public class TestDataModel
{
public string AgencyId;
public int Years;
public PropertyBagModel Overrides;
}
public class ParticipantFilterModel
{
public string[] ClassAndTier;
public string[] BargainingUnit;
public string[] Department;
}
public class PropertyBagModel
{
[JsonExtensionData]
private readonly Dictionary<string, JToken> _extensionData = new Dictionary<string, JToken>();
[JsonIgnore]
public readonly Dictionary<string, string> Values = new Dictionary<string, string>();
[JsonProperty(".plan", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, PropertyBagModel> ByPlan;
[JsonProperty(".classAndTier", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, PropertyBagModel> ByClassAndTier;
[JsonProperty(".bargainingUnit", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, PropertyBagModel> ByBarginingUnit;
[OnSerializing]
private void OnSerializing(StreamingContext context)
{
foreach (var kvp in Values)
_extensionData.Add(kvp.Key, kvp.Value);
}
[OnSerialized]
private void OnSerialized(StreamingContext context)
{
_extensionData.Clear();
}
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
Values.Clear();
foreach (var kvp in _extensionData.Where(x => x.Value.Type == JTokenType.String))
Values.Add(kvp.Key, kvp.Value.Value<string>());
_extensionData.Clear();
}
}
基本思想是这样的:
- JSON.NET 反序列化的 PropertyBagModel 填充了 ByPlan、ByClassAndTier 等字段,还填充了私有 _extensionData 字段。
- 然后 JSON.NET 调用私有 OnDeserialized() 方法,这会将数据从 _extensionData 移动到适当的 Values (否则将其放在地板上 - 如果您想知道它,大概可以记录它)。然后我们从 _extensionData 中删除额外的垃圾,这样它就不会消耗内存。
- 在序列化时, OnSerializing 方法会调用我们将内容移动到 _extensionData 中以便保存。
- 序列化完成后,调用 OnSerialized 并从 _extensionData 中删除多余的内容。
我们可以在需要时进一步删除并重新创建 _extensionData 字典,但我没有看到其中的真正价值,因为我没有使用大量这些对象。为此,我们只需在 OnSerializing 上创建并在 OnSerialized 上删除。在 OnDeserializing 上,我们可以释放它,而不是清除它。