简体   繁体   English

Newtonsoft Json.NET 不序列化 [Obsolete] 属性

[英]Newtonsoft Json.NET do not serialize [Obsolete] property

Is there a way to configure Json.NET to not serialize properties which have an [Obsolete] attribute?有没有办法将 Json.NET 配置为不序列化具有[Obsolete]属性的属性?

eg例如

public class Foo
{
    public int Id { get; set; }

    [Obsolete]
    public int Age { get; set; }
 }

 var foo = new Foo { Id = 123, Age = 23 };
 var json = JsonConvert.SerializeObject(foo);

In the above example, the json is {"Id":123,"Age":23}在上面的例子中,json 是{"Id":123,"Age":23}

I would like {"Id":123}我想要{"Id":123}

Yes, you can use a custom ContractResolver to exclude properties marked obsolete.是的,您可以使用自定义ContractResolver来排除标记为过时的属性。
Here is the code you would need for the resolver:这是解析器所需的代码:

public class ExcludeObsoletePropertiesResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty prop = base.CreateProperty(member, memberSerialization);
        if (prop.AttributeProvider.GetAttributes(true).OfType<ObsoleteAttribute>().Any())
        {
            prop.ShouldSerialize = obj => false;
        }
        return prop;
    }
}

Then use it like this:然后像这样使用它:

var settings = new JsonSerializerSettings
{
    ContractResolver = new ExcludeObsoletePropertiesResolver()
};
var json = JsonConvert.SerializeObject(foo, settings);

Working demo here: https://dotnetfiddle.net/gIRCD4这里的工作演示: https : //dotnetfiddle.net/gIRCD4

You can utilise conditional serialisation as documented here: https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm您可以使用此处记录的条件序列化: https : //www.newtonsoft.com/json/help/html/ConditionalProperties.htm

If you have control over the class and want to target specific properties you know upfront it would be easier to use the first mechanism, offering ShouldSerializeAge() method如果您可以控制类并希望针对您预先知道的特定属性,那么使用第一种机制会更容易,提供ShouldSerializeAge()方法

But most probably it seems you need something generic in this case you can create a IContractResolver class that uses Reflection to check whether a given property has the Obselete attribute但很可能在这种情况下,您似乎需要一些通用的东西,您可以创建一个IContractResolver类,该类使用反射来检查给定的属性是否具有Obselete属性

Expanding on Brian Rogers' answer: It's a little bit simpler/faster to filter out the members to exclude in an override of GetSerializableMembers() method rather than the CreateProperty(MemberInfo member, MemberSerialization memberSerialization) which gets called for on each MemberInfo returned by GetSerializedMembers() to avoid unnecessary calls to the CreateProperty method which does a bunch of reflection and delegate creation.扩展 Brian Rogers 的回答:在GetSerializableMembers()方法的覆盖中过滤掉要排除的成员要简单/更快,而不是在GetSerializedMembers()返回的每个MemberInfo上调用CreateProperty(MemberInfo member, MemberSerialization memberSerialization) GetSerializedMembers()以避免不必要地调用 CreateProperty 方法,该方法执行大量反射和委托创建。

public class ExcludeObsoletePropertiesResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        var members =  base.GetSerializableMembers(objectType);
        members.RemoveAll(m => m.IsDefined(typeof(ObsoleteAttribute), true));
        return members;
    }
}

Usage:用法:

var settings = new JsonSerializerSettings
{
    ContractResolver = new ExcludeObsoletePropertiesResolver()
};
var json = JsonConvert.SerializeObject(foo, settings);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM