反序列化复杂类型但将选定的属性保持为序列化
Deserializing a complex type but keep selected properties as serialized
我正在将复杂的 json 对象反序列化为 POCO,然后使用 Microsoft.Azure.Cosmos.Table SDK 将数据存储到 Azure table 存储.但是,SDK 不支持插入复杂类型。我正在寻找一种反序列化我的 json 的方法,使复杂类型保持序列化,只有简单类型被反序列化。
这是我的 class 定义:
public class Person
{
public string name {get; set;}
public int department {get; set;}
public List<Address> addresses {get; set;}
public Skill skill {get; set;}
}
现在,我需要反序列化我的 json,这样 Addresses 和 Skill 应该保留为 string,但其他属性应该被反序列化。这将允许我将整个对象存储到 Azure Table 存储中,并显示地址和技能的列。我知道 [JsonIgnore] 会简单地忽略我的 属性 这不是我需要的。
有什么办法可以做到吗?
这里的关键是使用不同的 class 来持久化,class 将从 JSON 反序列化,我们将其命名为 PersistablePerson
.
我可以想到两种方法:
方法 1 - 使用自定义转换器
根据@dbc 建议的,创建自定义转换器:
public class RawConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.TokenType != JsonToken.Null
? JRaw.Create(reader).ToString()
: null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteRawValue((string)value);
}
}
可持久化 class 看起来像这样:
public class PersistablePerson
{
public string name {get; set;}
public int department {get; set;}
[JsonConverter(typeof(RawConverter))]
public string addresses {get; set;}
[JsonConverter(typeof(RawConverter))]
public string skill {get; set;}
}
方法 2 - 使用双倍属性
在持久性 class 中,将 "complex" 属性加倍,以便每个这样的 属性 由两个表示:
- 一个字符串属性:包含在持久化中,被JSON序列化器忽略
- a
JToken
属性:由 JSON 序列化程序处理,从持久性中排除
JToken
属性 setter 和 getter 是读写字符串 属性.
的包装器
public class PersistablePerson
{
public string name {get; set;}
public int department {get; set;}
[JsonIgnore] // exclude from JSON serialization, include in persistence
public string addresses {get; set;}
[IgnoreProperty] // exclude from persistence
[JsonProperty("addresses")] // include in JSON serilization
public JToken addressesJson
{
get { return addresses != null ? JToken.Parse(addresses) : null; }
set { addresses = value.ToString(); }
}
[JsonIgnore] // exclude from JSON serialization, include in persistence
public string skill {get; set;}
[IgnoreProperty] // exclude from persistence
[JsonProperty("skill")] // include in JSON serilization
public JToken skillJson
{
get { return skill != null ? JToken.Parse(skill) : null; }
set { skill = value.ToString(); }
}
}
我正在将复杂的 json 对象反序列化为 POCO,然后使用 Microsoft.Azure.Cosmos.Table SDK 将数据存储到 Azure table 存储.但是,SDK 不支持插入复杂类型。我正在寻找一种反序列化我的 json 的方法,使复杂类型保持序列化,只有简单类型被反序列化。
这是我的 class 定义:
public class Person
{
public string name {get; set;}
public int department {get; set;}
public List<Address> addresses {get; set;}
public Skill skill {get; set;}
}
现在,我需要反序列化我的 json,这样 Addresses 和 Skill 应该保留为 string,但其他属性应该被反序列化。这将允许我将整个对象存储到 Azure Table 存储中,并显示地址和技能的列。我知道 [JsonIgnore] 会简单地忽略我的 属性 这不是我需要的。
有什么办法可以做到吗?
这里的关键是使用不同的 class 来持久化,class 将从 JSON 反序列化,我们将其命名为 PersistablePerson
.
我可以想到两种方法:
方法 1 - 使用自定义转换器
根据@dbc 建议的
public class RawConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.TokenType != JsonToken.Null
? JRaw.Create(reader).ToString()
: null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteRawValue((string)value);
}
}
可持久化 class 看起来像这样:
public class PersistablePerson
{
public string name {get; set;}
public int department {get; set;}
[JsonConverter(typeof(RawConverter))]
public string addresses {get; set;}
[JsonConverter(typeof(RawConverter))]
public string skill {get; set;}
}
方法 2 - 使用双倍属性
在持久性 class 中,将 "complex" 属性加倍,以便每个这样的 属性 由两个表示:
- 一个字符串属性:包含在持久化中,被JSON序列化器忽略
- a
JToken
属性:由 JSON 序列化程序处理,从持久性中排除
JToken
属性 setter 和 getter 是读写字符串 属性.
public class PersistablePerson
{
public string name {get; set;}
public int department {get; set;}
[JsonIgnore] // exclude from JSON serialization, include in persistence
public string addresses {get; set;}
[IgnoreProperty] // exclude from persistence
[JsonProperty("addresses")] // include in JSON serilization
public JToken addressesJson
{
get { return addresses != null ? JToken.Parse(addresses) : null; }
set { addresses = value.ToString(); }
}
[JsonIgnore] // exclude from JSON serialization, include in persistence
public string skill {get; set;}
[IgnoreProperty] // exclude from persistence
[JsonProperty("skill")] // include in JSON serilization
public JToken skillJson
{
get { return skill != null ? JToken.Parse(skill) : null; }
set { skill = value.ToString(); }
}
}