如何使用 NewtonSoft 库忽略空数组元素

Jes*_*ker 2 c# json.net

我有以下代码:

public City[] Cities { get; set; }
Run Code Online (Sandbox Code Playgroud)

在 City 类中,我有两个属性

public string Name { get; set; }
public string Code { get; set; }
Run Code Online (Sandbox Code Playgroud)

当出现此Cities字段为空的请求时,我想用 Newtonsoft 隐藏它。

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public City[] Cities { get; set; }
Run Code Online (Sandbox Code Playgroud)

但是我试过的这段代码不起作用,因为 Cities它不是空的,而是空的,并且请求在这个数组中总是有两个属性。

在这种情况下我应该如何使用 Newtonsoft?这里需要的对象是否有任何额外的检查?

Ali*_*ami 5

您应该在 JSON.NET 中使用条件属性序列化。我认为如果此属性为空或为 null,您将忽略此属性,因此,在包含Cities属性的类中添加此方法:

    // ignore a property on a condtion
    public bool ShouldSerializeCities() => Cities != null && Cities.Count > 0;
Run Code Online (Sandbox Code Playgroud)

更新 1:

正如@DavidG 提到的,如果字符串字段(名称和代码)为空或空,则上面的解决方法不会忽略它们。为了做到这一点,你需要利用DefaultValue

JsonConvert像这样定义设置:

        var settings = new JsonSerializerSettings {
            NullValueHandling = NullValueHandling.Ignore,
            DefaultValueHandling = DefaultValueHandling.Ignore
        };
Run Code Online (Sandbox Code Playgroud)

DefaultValue在您想要的字段/属性上使用属性:

public class City
{
    [DefaultValue("")]
    public string Name
    {
        get;
        set;
    }

    [DefaultValue("")]
    public string Code
    {
        get;
        set;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用您在上面创建的设置序列化您的对象:

JsonConvert.SerializeObject(obj, settings) ;
Run Code Online (Sandbox Code Playgroud)

例如,如果您的对象如下所示:

        var obj = new Foo{
            Cities = new  [] {
                new City() {Name = "A", Code = ""}
                , new City() {Name = "B", Code = "C"}
                , new City(){Name = "", Code = ""}
            }
        };
Run Code Online (Sandbox Code Playgroud)

结果将是:

{
  "Cities": [
    {
      "Name": "A"
    },
    {
      "Name": "B",
      "Code": "C"
    },
    {}
  ]
}
Run Code Online (Sandbox Code Playgroud)

我在 .NET Fiddle 上创建了一个项目来看看它是如何工作的。

如果你不喜欢创建新的设置,你仍然可以ShuldSerializeMemberName在你的City类中使用:

public class City
{
   public string Name{get;set;}

   public bool ShouldSerializeName() => !string.IsNullOrEmpty(Name);
}
Run Code Online (Sandbox Code Playgroud)