Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Default value for missing Complex properties with JSON.net (JsonConvert.SerializeObject or JsonConvert.DeSerializeObject)

I have a requirement where I need to set default value to the below complex property Instances using JsonProperty and DefaultValue.

I know we can achieve this for primitive properties as mentioned in the below link, but need to know how we can do it for complex properties.

Default value for missing properties with JSON.net

Below is the default Instances value I need to set using DefaultValue(). Please let me know how to achieve this.

Default value to be set to Instances property:

Instance instance = new Instance();
instance.Name = "XYZ";
instance.MyProperty = 11;

List<Instance> Instances = new List<Instance>();
Instances.Add(instance);

Code snippet:

public class DataSettings
{
  public DataSettings()
  {
    Instances = new List<Instance>();
  }

  [DefaultValue()] //How can I mention the above default value here ?
  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
  public List<Instance> Instances { get; set; }
}

public class Instance
{
  public string Name { get; set; }
  public int MyProperty { get; set; }
}
like image 430
ganvin Avatar asked Jul 09 '26 21:07

ganvin


1 Answers

As you've seen, attributes only support constant values, so you cannot set a complex value in an attribute. If you want to set a default value for a complex property during deserialization, a good approach is to use a serialization callback method, as shown below.

The idea is to add a method to your class which the serializer will call after deserialization is complete for the object. The callback must be a void method that accepts a StreamingContext as its only parameter, and it must be marked with an [OnDeserialized] attribute. The name of the method does not matter. Inside the callback method you can check whether the Instances list was populated, and if not, you can set the default value as you require.

public class DataSettings
{
    public DataSettings()
    {
        Instances = new List<Instance>();
    }

    public List<Instance> Instances { get; set; }

    [OnDeserialized]
    internal void SetDefaultValuesAfterDeserialization(StreamingContext context)
    {
        if (Instances == null || !Instances.Any())
        {
            Instances = new List<Instance>
            {
                new Instance { Name = "XYZ", MyProperty = 11 }
            };
        }
    }
}

Here is a working fiddle to demonstrate the concept: https://dotnetfiddle.net/uCGP5X

like image 89
Brian Rogers Avatar answered Jul 13 '26 19:07

Brian Rogers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!