首页 文章

如何使用json.net忽略类中的属性null

提问于
浏览
389

我正在使用Json.NET将类序列化为JSON .

我有这样的课:

class Test1
{
    [JsonProperty("id")]
    public string ID { get; set; }
    [JsonProperty("label")]
    public string Label { get; set; }
    [JsonProperty("url")]
    public string URL { get; set; }
    [JsonProperty("item")]
    public List<Test2> Test2List { get; set; }
}

我想仅在 Test2Listnull 时才向 Test2List 属性添加 JsonIgnore() 属性 . 如果它不为null,那么我想将它包含在我的json中 .

10 回答

  • 10

    你可以写: [JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]

    它还负责不使用默认值(不仅为null)序列化属性 . 例如,它可用于枚举 .

  • 668
    var settings = new JsonSerializerSettings();
    settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    settings.NullValueHandling = NullValueHandling.Ignore;
    //you can add multiple settings and then use it
    var bodyAsJson = JsonConvert.SerializeObject(body, Formatting.Indented, settings);
    
  • 0

    稍微阐述一下GlennG非常有用的答案(将语法从C#转换为VB.Net并不总是“显而易见”),您还可以修饰单个类属性来管理如何处理空值 . 如果这样做,请不要使用GlennG建议的全局JsonSerializerSettings,否则它将覆盖单个装饰 . 如果您希望在JSON中显示空项目,那么这会派上用场,因此消费者不必进行任何特殊处理 . 例如,如果消费者需要知道可选项的数组通常是可用的,但当前是空的...属性声明中的装饰如下所示:

    <JsonPropertyAttribute("MyProperty", DefaultValueHandling:=NullValueHandling.Include)> Public Property MyProperty As New List(of String)
    

    对于那些您不希望在JSON更改 :=NullValueHandling.Include:=NullValueHandling.Ignore 中出现的属性 . 顺便说一句 - 我发现你可以为XML和JSON序列化装饰一个属性就好了(只是将它们放在彼此旁边) . 这使我可以随意调用dotnet中的XML序列化程序或NewtonSoft序列化程序 - 两者并排工作,我的客户可以选择使用XML或JSON . 由于我的顾客需要两者,所以这就像门把手上的鼻涕一样光滑!

  • 4

    使用 JsonProperty 属性的备用解决方案:

    [JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
    //or
    [JsonProperty("property_name", NullValueHandling=NullValueHandling.Ignore)]
    

    this online doc所示 .

  • 498

    这是一个类似的选项,但提供了另一种选择:

    public class DefaultJsonSerializer : JsonSerializerSettings
    {
        public DefaultJsonSerializer()
        {
            NullValueHandling = NullValueHandling.Ignore;
        }
    }
    

    然后,我像这样使用它:

    JsonConvert.SerializeObject(postObj, new DefaultJsonSerializer());
    

    这里的区别在于:

    • 通过实例化和配置 JsonSerializerSettings 每个使用的位置来减少重复的代码 .

    • 节省配置要序列化的每个对象的每个属性的时间 .

    • 仍然为其他开发人员提供了序列化选项的灵活性,而不是在可重用对象上明确指定属性 .

    • 我的用例是代码是第三方库,我不想强迫那些想要重用我的类的开发人员使用序列化选项 .

    • 潜在的缺点是它对单个序列化很重要 .

  • 19

    适应@Mychief的/ @ amit的答案,但对于使用VB的人来说

    Dim JSONOut As String = JsonConvert.SerializeObject(
               myContainerObject, 
               New JsonSerializerSettings With {
                     .NullValueHandling = NullValueHandling.Ignore
                   }
      )
    

    见:"Object Initializers: Named and Anonymous Types (Visual Basic)"

    https://msdn.microsoft.com/en-us/library/bb385125.aspx

  • 0

    根据James Newton King的说法:如果你自己创建序列化程序而不是使用JavaScriptConvert,那么可以设置一个NullValueHandling property来忽略它 .

    这是一个示例:

    JsonSerializer _jsonWriter = new JsonSerializer {
                                     NullValueHandling = NullValueHandling.Ignore
                                 };
    

    或者,正如@amit所建议的那样

    JsonConvert.SerializeObject(myObject, 
                                Newtonsoft.Json.Formatting.None, 
                                new JsonSerializerSettings { 
                                    NullValueHandling = NullValueHandling.Ignore
                                });
    
  • 49

    你可以这样做来忽略你正在序列化的对象中的所有空值,然后任何空属性都不会出现在JSON中

    JsonSerializerSettings settings = new JsonSerializerSettings();
    settings.NullValueHandling = NullValueHandling.Ignore;
    var myJson = JsonConvert.SerializeObject(myObject, settings);
    
  • 19

    可以在他们网站上的这个链接中看到(http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size.aspx)我支持使用[Default()]指定默认值

    取自链接

    public class Invoice
    {
      public string Company { get; set; }
      public decimal Amount { get; set; }
    
      // false is default value of bool
      public bool Paid { get; set; }
      // null is default value of nullable
      public DateTime? PaidDate { get; set; }
    
      // customize default values
      [DefaultValue(30)]
      public int FollowUpDays { get; set; }
      [DefaultValue("")]
      public string FollowUpEmailAddress { get; set; }
    }
    
    
    Invoice invoice = new Invoice
    {
      Company = "Acme Ltd.",
      Amount = 50.0m,
      Paid = false,
      FollowUpDays = 30,
      FollowUpEmailAddress = string.Empty,
      PaidDate = null
    };
    
    string included = JsonConvert.SerializeObject(invoice,
      Formatting.Indented,
      new JsonSerializerSettings { });
    
    // {
    //   "Company": "Acme Ltd.",
    //   "Amount": 50.0,
    //   "Paid": false,
    //   "PaidDate": null,
    //   "FollowUpDays": 30,
    //   "FollowUpEmailAddress": ""
    // }
    
    string ignored = JsonConvert.SerializeObject(invoice,
      Formatting.Indented,
      new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
    
    // {
    //   "Company": "Acme Ltd.",
    //   "Amount": 50.0
    // }
    
  • 0

    与@ sirthomas的答案类似,JSON.NET也在 DataMemberAttribute 上尊重the EmitDefaultValue property

    [DataMember(Name="property_name", EmitDefaultValue=false)]
    

    如果您已在模型类型中使用 [DataContract][DataMember] 并且不想添加特定于JSON.NET的属性,则可能需要这样做 .

相关问题