Json序列化在不分配值时忽略属性,但在分配空值时应存在属性

时间:2020-06-16 08:08:12

标签: c# json serialization json.net

我有一个定义为Car的类,我想序列化为JSON,因为当您不向属性分配任何内容时忽略属性,但是如果我将其分配为null,则该属性应该以JSON出现。

示例:

 public class Car
    {
        public int CarId { get; set; }
        public string Brand { get; set; }
        public string Model { get; set; }
        public string Color { get; set; }
    }
  1. 案例1

如果我按如下所示分配值

            Car car = new Car();
            car.CarId = 1;
            car.Color = "Black";
            car.Brand = "Hundai";
            car.Model = null;

预期的JSON将显示为

{
  "CarId": 1,
  "Brand": "Hundai",
  "Model": null,
  "Color": "Black"
}
  1. 案例2

如果我按以下方式分配值(未分配 car.Model

            Car car = new Car();
            car.CarId = 1;
            car.Color = "Black";
            car.Brand = "Hundai";

预期的JSON为

{
  "CarId": 1,
  "Brand": "Hundai",
  "Color": "Black"
}

我使用了如下的Newtonsoft Json库,但无法获得预期的输出

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

2 个答案:

答案 0 :(得分:0)

步骤1:修改Car类,如下所示:

public class Car {
    public int CarId { get; set; }
    public string Brand { get; set; } = "null"; // Default value
    public string Model { get; set; } = "null"; // Default value
    public string Color { get; set; } = "null"; // Default value

    // Serialize only when the default value changed
    public bool ShouldSerializeBrand() {
        return string.IsNullOrWhiteSpace(Brand) || !Brand.Equals("null");
    }

    public bool ShouldSerializeModel() {
        return string.IsNullOrWhiteSpace(Model) || !Model.Equals("null");
    }

    public bool ShouldSerializeColor() {
        return string.IsNullOrWhiteSpace(Color) || !Color.Equals("null");
    }

}

第2步:现在,按如下所示创建汽车对象:

 var car = new Car {
     CarId = 1,
     Brand = "Hundai",
     Model = null
 };

步骤3:序列化对象,如下所示:

var SerializedCar = JsonConvert.SerializeObject(car, Formatting.Indented);

第4步:将输出写入控制台

Console.WriteLine(SerializedCar);

最后:结果完全符合您的预期:

{
  "CarId": 1,
  "Brand": "Hundai",
  "Model": null
}

我在不同情况下进行了测试,效果很好。

答案 1 :(得分:0)

要更通用,您必须创建自己的ContractResolver类

第1步:汽车等级应如下:

public class Car {
    public int CarId { get; set; }
    public string Brand { get; set; } = "null"; // Default value
    public string Model { get; set; } = "null"; // Default value
    public string Color { get; set; } = "null"; // Default value
}

步骤2:您将需要创建以下类:

public class ShouldSerializeContractResolver : DefaultContractResolver {
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        if (!property.PropertyName.Equals("CarId")) {
            property.ShouldSerialize =
                instance => {
                    var car = (Car)instance;
                    var value = car.GetType().GetProperty(property.PropertyName).GetValue(car, null);
                    return value == null || !value.ToString().Equals("null");
                };
        }
        return property;
    }
}

步骤3:创建汽车对象:

var car = new Car {
    CarId = 1,
    Brand = "Hundai",
    Model = null
};

步骤4:序列化对象-注意我们如何在此处创建ContractResolver

var SerializedCar = JsonConvert.SerializeObject(car, 
   Formatting.Indented, 
   new JsonSerializerSettings {ContractResolver = new ShouldSerializeContractResolver()
});

步骤5:打印输出:

Console.WriteLine(SerializedCar);

最后:结果:

   {
       "CarId": 1,
       "Brand": "Hundai",
       "Model": null
   }