TusharJ
TusharJ

Reputation: 1263

Excluding enum properties with default values in json response

I have a model for my api response which has a property of type enum. The enum property gets populated in only some scenarios rest of the scenario it gets the default value of 0

output {
prop1: "ABCD"
prop2: 0 //// this is enum property defaulting to zero
}

I tried using the custom jsonconverter but this does not really solve the problem as I can only assign a string value to it.
How can i exclude the enum property from the response if it has the default value.

Upvotes: 2

Views: 2766

Answers (2)

JotaBe
JotaBe

Reputation: 39025

In most versions of ASP.NET Web API the default JSON serializer is JSON.NET.

Tou can combine two things to achieve what you need:

  • Specify the default value handling in the Web API serializer configuration, like this: config.Formatters.JsonFormatter.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Ignore
  • Use the DefaultValueAttribute to specify which is the default that shouldn't be serialized, if not the "usual default": null for objects and nullables, 0 for numbers, and so on.

For your specific case of enum, you can define what is the default value in your enum, even if it's not 0.

For example, if you want to skip the serialization of ExpiryPeriod property in a class, when its value is 30, apart from setting the DefaultValueHandling.Ignore, pdecorate the property like this

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

NOTE: if you want to use JSON.NET to deserialize to the default value, you must use the DefaultValueHandling.IgnoreAndPopulate. This means that, if the property value is not found when deserializing the JSON text, the property will be created with the specified default value of 30.

Full example with Enum values:

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}";
        }
    }
}

which outputs:

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

As you can see, even if Seize.M is not the default (0) value of the enum, it's skipped from the serialization and used to deserialize the property if it's missing in the json.

Upvotes: 0

TusharJ
TusharJ

Reputation: 1263

This is resolved doing two things
1. Make the enum property as nullable and initialized it in the constructor to null.
2. Use json serializer setting NullValueHandling = NullValueHandling.Ignore

Upvotes: 1

Related Questions