【问题标题】:Excluding enum properties with default values in json response在 json 响应中排除具有默认值的枚举属性
【发布时间】:2016-10-27 09:40:36
【问题描述】:

我的 api 响应模型具有枚举类型的属性。枚举属性仅在某些场景中填充,其余场景中它获取默认值 0

输出 {
prop1:“ABCD”
prop2: 0 //// 这是枚举属性,默认为零
}

我尝试使用自定义 jsonconverter 但这并不能真正解决问题,因为我只能为其分配一个字符串值。
如果枚举属性具有默认值,我如何从响应中排除它。

【问题讨论】:

标签: c# json serialization asp.net-web-api enums


【解决方案1】:

这通过两件事解决
1。将枚举属性设为可空,并在构造函数中将其初始化为空。
2。使用 json 序列化器设置 NullValueHandling = NullValueHandling.Ignore

【讨论】:

    【解决方案2】:

    在大多数版本的 ASP.NET Web API 中,默认的 JSON 序列化器是 JSON.NET。

    你可以结合两件事来实现你所需要的:

    • 在 Web API 序列化程序配置中指定 default value handling,如下所示:config.Formatters.JsonFormatter.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Ignore
    • 使用DefaultValueAttribute 指定不应该序列化的默认值,如果不是“通常的默认值”:null 表示对象和可空值,0 表示数字,等等。

    对于您的特定枚举情况,您可以定义枚举中的默认值,即使它不是 0。

    例如,如果你想跳过一个类中ExpiryPeriod属性的序列化,当它的值为30时,除了设置DefaultValueHandling.Ignore之外,像这样装饰属性

    public class Voucher
    {
        [DefaultValue(30)]
        public int ExpiryPeriod { get; set; }
    }
    

    注意:如果要使用 JSON.NET 反序列化为默认值,则必须使用 DefaultValueHandling.IgnoreAndPopulate。这意味着,如果在反序列化 JSON 文本时未找到该属性值,则会使用指定的默认值 30 创建该属性。

    枚举值的完整示例:

    using System;
    using System.ComponentModel;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;
    
                        
    public class Program
    {
        public static void Main()
        {
            var tshirts = new TShirt[]
            {
                new TShirt { Model = "Hawaii 2", Size = Size.M },
                new TShirt { Model = "La casa de papel", Size = Size.XL },
            };
    
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
            settings.Converters.Add(new StringEnumConverter());
    
            foreach(var tshirt in tshirts)
            {
                Console.WriteLine("Original T-Shirt");
                Console.WriteLine(tshirt);
                Console.WriteLine();
    
                var serialized = JsonConvert.SerializeObject(tshirt, Formatting.Indented, settings);
                Console.WriteLine("Serialized T-Shirt");
                Console.WriteLine(serialized);
                Console.WriteLine();
            
                Console.WriteLine("Deserialized T-Shirt");
                var deserialized = JsonConvert.DeserializeObject<TShirt>(serialized, settings);
                Console.WriteLine(deserialized);
                Console.WriteLine();
                Console.WriteLine();
            }   
        }
        
        public enum Size
        {
            XL,
            L,
            M,
            X,
            XS
        }
        
        public class TShirt
        {
            public string Model { get; set; }
            
            [DefaultValue(Size.M)]
            public Size Size { get; set; } 
            
            public override string ToString()
            {
                return $"· Model: {Model}\r\n· Size: {Size}";
            }
        }
    }
    

    哪个输出:

    Original T-Shirt
    · Model: Hawaii 2
    · Size: M
    
    Serialized T-Shirt
    {
      "Model": "Hawaii 2"
    }
    
    Deserialized T-Shirt
    · Model: Hawaii 2
    · Size: M
    
    
    Original T-Shirt
    · Model: La casa de papel
    · Size: XL
    
    Serialized T-Shirt
    {
      "Model": "La casa de papel",
      "Size": "XL"
    }
    
    Deserialized T-Shirt
    · Model: La casa de papel
    · Size: XL
    

    如您所见,即使Seize.M 不是枚举的默认 (0) 值,它也会从序列化中跳过并用于反序列化 json 中缺少的属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 2015-03-04
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多