System.Text.Json 序列/反序列化 abstrac
2021-08-25 本文已影响0人
gruan
public enum SKUTypes
{
/// <summary>
/// 普通,SKU 的价格直接体现在 SKU 中
/// </summary>
Normal = 0,
/// <summary>
/// 日历类型,SKU 的价格需要从日历价格接口中取
/// </summary>
Daily = 1,
/// <summary>
/// 需要选择日期的, 比如酒店, 需要选择日期才能查价格
/// </summary>
ChoiceDate = 2
}
[JsonConverter(typeof(SKUConverter))]
public abstract class BaseSKU
{
/// <summary>
/// 是否是日历类型的 SKU
/// </summary>
public abstract SKUTypes SKUType { get; }
...
...
public class SKU : BaseSKU
{
/// <summary>
///
/// </summary>
public override SKUTypes SKUType => SKUTypes.Normal;
...
...
public class DailySKU : BaseSKU
{
/// <summary>
///
/// </summary>
public override SKUTypes SKUType => SKUTypes.Daily;
...
...
public class SKUConverter : JsonConverter<BaseSKU>
{
/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <param name="typeToConvert"></param>
/// <param name="options"></param>
/// <returns></returns>
public override BaseSKU Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//reader 是 struct , 如果直接用 reader 的话, 会因为位置已改变, 下面的 Deserializer 报错
var tmpReader = reader;
var detect = JsonSerializer.Deserialize<TypeDetectSKU>(ref tmpReader, options);
return detect.SKUType switch
{
SKUTypes.Daily => (BaseSKU)JsonSerializer.Deserialize(ref reader, typeof(DailySKU), options),
SKUTypes.Normal => (BaseSKU)JsonSerializer.Deserialize(ref reader, typeof(SKU), options),
SKUTypes.ChoiceDate => (BaseSKU)JsonSerializer.Deserialize(ref reader, typeof(HotelSKU), options),
_ => throw new NotSupportedException($"SKUType:{detect.SKUType}"),
};
}
/// <summary>
///
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="options"></param>
public override void Write(Utf8JsonWriter writer, BaseSKU value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value?.GetType() ?? typeof(object), options);
}
/// <summary>
///
/// </summary>
private class TypeDetectSKU : BaseSKU
{
/// <summary>
///
/// </summary>
[JsonPropertyName("SKUType")]
public SKUTypes _SKUType { get; set; }
/// <summary>
///
/// </summary>
[JsonIgnore]
public override SKUTypes SKUType => this._SKUType;
}
}