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

时间:2019-06-20 11:45:08

标签: c# json.net

是否可以将Json.NET配置为不对具有Mockito.verify(entityManagerMock.createQuery(ArgumentMatchers.anyString())).executeUpdate(); 属性的属性进行序列化?

例如

[Obsolete]

在上面的示例中,json是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);

我想要{"Id":123,"Age":23}

3 个答案:

答案 0 :(得分:6)

是的,您可以使用自定义ContractResolver来排除标记为过时的属性。
这是解析器所需的代码:

class Bird {
  avgHeight: Number
  avgWidth: Number
  wingSpan: Number

  constructor(avgHeight: Number, avgWidth: Number, wingSpan: Number) {
    this.avgHeight = avgHeight;
    this.avgWidth = avgWidth;
    this.wingSpan = wingSpan;
  }
}

class Pigeon extends Bird {}
class Ostrich extends Bird {}

const updateBird = (bird: Bird, height: Number, span: Number): Bird => {
  const newBird = Object.assign(
    bird,
    Object.create(
      bird instanceof Pigeon 
        ? bird as Pigeon 
        : bird as Ostrich
    )
  );

  // Update logic only happens below and is not 
  // duplicated based on the bird type

  if (bird.avgWidth === 0) {
    // Only update value if X condition is met
    // Condition based on passed in object
    newBird.avgWidth = 100
  }

  newBird.avgHeight = height;

  if (span > 0) {
    // Only update value if X condition is met
    newBird.wingSpan = Number(span) * 2;
  }

  return newBird;
}

然后像这样使用它:

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;
    }
}

此处的工作演示:https://dotnetfiddle.net/gIRCD4

答案 1 :(得分:1)

您可以使用此处记录的条件序列化:https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm

如果您可以控制该类并希望定位特定的属性,那么使用第一种机制(提供ShouldSerializeAge()方法会更容易)

但是在这种情况下,很可能您似乎需要通用的东西,您可以创建一个IContractResolver类,该类使用反射来检查给定的属性是否具有Obselete属性

答案 2 :(得分:0)

扩展Brian Rogers的答案:过滤掉要覆盖在GetSerializableMembers()方法而不是每个{{ CreateProperty(MemberInfo member, MemberSerialization memberSerialization)返回的1}}以避免不必要地调用CreateProperty方法,该方法会进行大量的反射和委托创建。

MemberInfo

用法:

GetSerializedMembers()