C#可扩展的解决方案,使用Json.Net过滤掉基于用户交互的属性



我正在使用C#Newtonsoft.net将数据序列化到Json中。在我的程序中,我将让用户与我的部分数据交互,我只希望序列化的数据是他们交互的数据。

下面的代码显示了一个创建类a并与to属性交互的示例。

[DataContract]
public class B
{
  [DataMember]
  public int Property1 { get; set; } = 0;
  [DataMember]
  public int Property2 { get; set; } = 0;
}
[DataContract]
public class A
{
  [DataMember]
  public int Property1 { get; set; } = 0;
  [DataMember]
  public int Property2 { get; set; } = 0;
  [DataMember]
  public B B { get; set; } = new B();
}
public class JsonTester
{
  public void Test()
  {
    var a = new A();
    a.Property1 = 1;
    a.B.Property1 = 1;
    var json = JsonConvert.SerializeObject(a, new JsonSerializerSettings()
    {
      ContractResolver = new JsonContractResolver()
    });
  }
}

我预期的json输出如下:

{
  "Property1": 1,
  "B": {
    "Property1": 1
  }
}

正如您所注意到的,Property2不在json中,因为我只设置了a.Property1/a.B.Property1。

如果我的代码没有.B.Property1=1,我希望json看起来像这样:

{
  "Property1": 1
}

现在,问题是如何以最可扩展的方式来实现这一点。显然,为每个属性创建单独的bool并不是一个可扩展的解决方案。

有很多方法可以解决这个问题。

您可以使用可为null的类型和NullValueHandling.Ignore枚举

序列化和反序列化对象时包含null值。

或者您可以使用DefaultValueHandling.Ignore

忽略成员值与成员值相同的成员序列化对象以使其不写入时的默认值JSON。此选项将忽略所有默认值(例如对象和可为null的类型;0表示整数、小数和浮点点数;布尔值为false(。忽略的默认值可以通过在属性上放置DefaultValueAttribute来更改。

示例

public class B
{
   [DefaultValue(1)]
   public int Property1 { get; set; }
   public int Property2 { get; set; }
}
public class A
{
   [DefaultValue(1)]
   public int Property1 { get; set; } 
   public int Property2 { get; set; } 
   public B B { get; set; } = new B();
}

用法

var a = new A();
a.Property1 = 1;
a.B.Property1 = 2;
var settings = new JsonSerializerSettings()
{
   DefaultValueHandling = DefaultValueHandling.Ignore,
   NullValueHandling = NullValueHandling.Ignore
};
var json = JsonConvert.SerializeObject(a, Newtonsoft.Json.Formatting.Indented, settings);
Console.WriteLine(json);

输出

{
  "B": {
    "Property1": 2
  }
}

最新更新