gpt4 book ai didi

c# - 如何从 JSON.NET 序列化中省略继承属性

转载 作者:行者123 更新时间:2023-11-30 12:21:45 26 4
gpt4 key购买 nike

如果我有以下类,我想使用 JSON.NET 进行序列化:

[DataContract]
public class Thing
{
[DataMember(Name = "@context")]
public string Context => "http://schema.org"
}

[DataContract]
public class Organization : Thing
{
[DataMember(Name = "address")]
public Address Address { get; set; }

...
}

[DataContract]
public class Address : Thing
{
...
}

当我使用 JSON.NET 序列化一个组织时,我得到:

{
"@context": "http://schema.org",
"address": {
"@context": "http://schema.org",
...
}
...
}

确保 @context 属性仅出现在顶级 Organization 对象中而不出现在 Address 中的最有效方法是什么对象?

最佳答案

如果 OrganizationThing 的唯一顶级后代,并且 Organization 类型的字段也不会出现在序列化对象中,您可能很容易通过在 Thing 中定义 ShouldSerializeContext 来做到这一点,如下所示:

[DataContract]
public class Thing
{
[DataMember(Name = "@context")]
public string Context => "http://schema.org";
public bool ShouldSerializeContext() { return this is Organization; }
}

演示:https://dotnetfiddle.net/GjmfbA


如果 Thing 的任何后代可能充当根对象,您可能需要实现自定义转换器。在此转换器的 WriteJson 方法中,您可以过滤要序列化的属性。要从除根对象之外的所有对象中删除 Context 属性,请检查 writer.Path,这对于根对象将是一个空字符串:

[DataContract]
[JsonConverter(typeof(NoContextConverter))]
public class Thing
{
[DataMember(Name = "@context")]
public string Context => "http://schema.org";
}

// ...............

public class NoContextConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var props = value.GetType().GetProperties()
.Where(p => Attribute.IsDefined(p, typeof(DataMemberAttribute)))
.ToList();
if (writer.Path != "")
props.RemoveAll(p => p.Name == "Context");

writer.WriteStartObject();
foreach (var prop in props)
{
writer.WritePropertyName(prop.GetCustomAttribute<DataMemberAttribute>().Name);
serializer.Serialize(writer, prop.GetValue(value, null));
}
writer.WriteEndObject();
}

public override bool CanConvert(Type objectType)
{
return typeof(Thing).IsAssignableFrom(objectType);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

演示:https://dotnetfiddle.net/cIlXID

注意出于某种原因,dotnetfiddle.net 不允许使用 System.Runtime.Serialization 中的 DataContractAttributeDataMemberAttribute 所以我不得不注释掉相关行在此演示中。

关于c# - 如何从 JSON.NET 序列化中省略继承属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44453822/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com