我使用的是Json。将类序列化为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; }
}

我想仅当Test2List为空时才向Test2List属性添加JsonIgnore()属性。如果它不是空的,那么我想包括它在我的json。


当前回答

在我的情况下,使用。net 6这是解决方案:

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

更多信息请点击这里。

其他回答

正如James Newton King所述:如果你自己创建序列化器,而不是使用JavaScriptConvert,那么你可以将NullValueHandling属性设置为忽略。

下面是一个例子:

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

或者,按照@amit的建议

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

这并没有完全回答最初的问题,但根据用例可能证明是有用的。(因为我是在搜索之后才来到这里的,所以它可能对其他人有用。)

在我最近的经验中,我正在使用PATCH api。如果指定了一个属性但没有给定值(null/undefined,因为它是js),那么该属性和值将从正在修补的对象中移除。所以我在寻找一种方法来选择性地构建一个对象,它可以以这样一种方式序列化,这样就可以工作。

我记得看到过ExpandoObject,但直到今天才有一个真正的用例。这允许您动态地构建对象,因此您不会有null属性,除非您希望它们在那里。

这是一个工作提琴,与下面的代码。

结果:

Standard class serialization
    noName: {"Name":null,"Company":"Acme"}
    noCompany: {"Name":"Fred Foo","Company":null}
    defaultEmpty: {"Name":null,"Company":null}
ExpandoObject serialization
    noName: {"Company":"Acme"}
    noCompany: {"name":"Fred Foo"}
    defaultEmpty: {}

代码:

using Newtonsoft.Json;
using System;
using System.Dynamic;
                    
public class Program
{
    public static void Main()
    {
        SampleObject noName = new SampleObject() { Company = "Acme" };
        SampleObject noCompany = new SampleObject() { Name = "Fred Foo" };
        SampleObject defaultEmpty = new SampleObject();
        
        
        Console.WriteLine("Standard class serialization");
        Console.WriteLine($"    noName: { JsonConvert.SerializeObject(noName) }");
        Console.WriteLine($"    noCompany: { JsonConvert.SerializeObject(noCompany) }");
        Console.WriteLine($"    defaultEmpty: { JsonConvert.SerializeObject(defaultEmpty) }");
        
        
        Console.WriteLine("ExpandoObject serialization");
        Console.WriteLine($"    noName: { JsonConvert.SerializeObject(noName.CreateDynamicForPatch()) }");
        Console.WriteLine($"    noCompany: { JsonConvert.SerializeObject(noCompany.CreateDynamicForPatch()) }");
        Console.WriteLine($"    defaultEmpty: { JsonConvert.SerializeObject(defaultEmpty.CreateDynamicForPatch()) }");
    }
}

public class SampleObject {
    public string Name { get; set; }
    public string Company { get; set; }
    
    public object CreateDynamicForPatch()
    {
        dynamic x = new ExpandoObject();
        
        if (!string.IsNullOrWhiteSpace(Name))
        {
            x.name = Name;
        }
        
        if (!string.IsNullOrEmpty(Company))
        {
            x.Company = Company;
        }
        
        return x;
    }
}

可以在他们的网站(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
// }

.Net 6 - 在Program.cs中添加代码。这将忽略类或记录属性,如果它是空的。

using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.AddJsonOptions(opts =>
{
    var enumConverter = new JsonStringEnumConverter();
    opts.JsonSerializerOptions.Converters.Add(enumConverter);
    opts.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault | JsonIgnoreCondition.WhenWritingNull;
});

与Json。网

 public class Movie
 {
            public string Name { get; set; }
            public string Description { get; set; }
            public string Classification { get; set; }
            public string Studio { get; set; }
            public DateTime? ReleaseDate { get; set; }
            public List<string> ReleaseCountries { get; set; }
 }

 Movie movie = new Movie();
 movie.Name = "Bad Boys III";
 movie.Description = "It's no Bad Boys";

 string ignored = JsonConvert.SerializeObject(movie,
            Formatting.Indented,
            new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

结果将是:

{
   "Name": "Bad Boys III",
   "Description": "It's no Bad Boys"
 }