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

C#基于用户交互使用Json.Net过滤属性的可扩展解决方案,c#,serialization,json.net,scalability,C#,Serialization,Json.net,Scalability,我正在使用C#Newtonsoft.net将数据序列化为Json。在我的程序中,我将让用户与我的部分数据交互,我只希望序列化的数据是他们交互的数据 下面的代码显示了创建类a并与to属性交互的示例 [DataContract] public class B { [DataMember] public int Property1 { get; set; } = 0; [DataMember] public int Property2 { get; set; } = 0; } [D

我正在使用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

如果我的代码没有a.B.Property1=1,我希望json如下所示:

{
  "Property1": 1
}

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

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

可以使用可为空的类型和枚举

序列化和反序列化对象时包含空值

或者您可以使用
DefaultValueHandling.Ignore

忽略成员值与成员值相同的成员 序列化对象以使其不写入时的默认值 JSON。此选项将忽略所有默认值(例如,对于 对象和可空类型;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);
用法

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

这是永久性的忽略。你为什么使用
[DataContract]
有什么原因吗?我想我对这个问题不是很清楚这不是关于处理默认值,而是当与用户发生交互时。我将加载数据到某个状态。。。。。然后,用户将触摸属性