c# - JSON.net TypeNameHandling : 自定义 Auto
问题描述
我正在使用 JSON.net 序列化类并使用 TypeNameHandling=Auto 插入“$type”注释。为了这个例子,假设这是我的课:
[JsonObject]
public class MyClass
{
[JsonProperty]
public ISomeInterfaceA MyA { get; set; }
[JsonProperty]
public ISomeInterfaceB MyB { get; set; }
}
这样,“MyA”和“MyB”都会收到“$type”属性。不幸的是,我处于一个奇怪的情况,我需要“MyA”来拥有“$type”,但“MyB”不应该有“$type”。json.net 是否有任何东西可以让我自定义 TypeNameHandling.Auto 的行为,以便我可以手动选择我想要的位置?
至于我为什么要做这样的事情,复杂的原因是我正在从另一个遗留序列化器迁移到 JSON.net,并且我试图最小化旧序列化器和新序列化器之间的差异,以避免重写大大量使用 JSON 的 JavaScript 代码。
解决方案
您可以使用自定义转换器来实现此目的。
说这是你的课:
[JsonObject]
public class MyClass {
[JsonProperty]
public ISomeInterfaceA MyA { get; set; }
[JsonProperty]
[JsonConverter(typeof(NoTypeConverter))]
public ISomeInterfaceA MyB { get; set; }
}
我们需要一个自定义转换器:
public class NoTypeConverter: JsonConverter<ISomeInterfaceA> {
public override ISomeInterfaceA ReadJson(JsonReader reader, Type objectType, ISomeInterfaceA existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, ISomeInterfaceA value, JsonSerializer serializer)
{
// Note: this is not the most efficient way to do this, but you can customise this how you see fit.
writer.WriteRawValue(JsonConvert.SerializeObject(value));
}
public override bool CanWrite => true;
public override bool CanRead => false;
}
然后:
var stuff = JsonConvert.SerializeObject(new MyClass
{ MyA = new A { Banana = "cheese" },
MyB = new A { Banana = "notype"} },
new JsonSerializerSettings{ TypeNameHandling=TypeNameHandling.Auto });
Console.WriteLine(stuff); // {"MyA":{"$type":"whatever, here","Banana":"cheese"},"MyB":{"Banana":"notype"}}
但是请注意,您不能以这种方式将 BACK 反序列化为您的类型,因为缺少类型信息MyB
var x = JsonConvert.DeserializeObject<MyClass>(stuff,
new JsonSerializerSettings{ TypeNameHandling=TypeNameHandling.Auto });
那会抛出
未处理的异常。Newtonsoft.Json.JsonSerializationException:无法创建 ISomeInterfaceA 类型的实例。类型是接口或抽象类,不能实例化。路径“MyB.Banana”,第 1 行,位置 69。
推荐阅读
- python - glOrtho 不工作它仍然被映射到默认坐标
- reactjs - 259 / 5000 Wyniki tłumaczenia 搜索引擎 - 从状态数组中消失的项目
- python - 尝试使用 Python 将解析的数据导出到 CSV 文件,但我不知道如何导出多于一行
- typescript - 如何确保 ionic-selectable 可以运行 onChange 事件两次?
- ios - PHAsset 视频 EXIF 元数据检索
- c++ - C++ 随机字符串输出问题
- python - 我收到一个错误“
当我使用 __slots__ 时返回了带有错误集的结果 - python - CV2为图像返回NoneType?
- django - 如果我在集群上使用 Ingress-Nginx 服务,是否需要在 Kubernetes 集群中使用 nginx 容器来提供静态文件?
- wordpress - 当您复制一个部分并隐藏一个用于移动设备和一个用于桌面时,使锚点起作用