When developing web services in C# on ASP.NET Core using REST you will often provide responses in JSON.
The go-to framework to handle JSON in ASP.NET Core is Newtonsoft and there are a number of different ways you can handle default values and null values in your responses depending on how you want to display this data to your consumers.
Default values
Before I explain how we do this it is important to understand what the default values are of certain types as that can determine how you use and configure the handling of default values.
If we take a bool
type, for example, it can have a value of true
or false
. The default value of a bool
is in fact false
.
If you take an int
the default value for this is 0
.
Below is a quick table of some of the common default values:
Type | Default Value |
bool | false |
byte | 0 |
char | '\0' |
decimal | 0M |
double | 0.0D |
float | 0.0F |
int | 0 |
long | 0L |
sbyte | 0 |
short | 0 |
We can now understand how we want to display values if a field we are displaying in a JSON response is the default value.
If we have an int
field that stores a count do you want to display the field if it is the default value 0
or would you prefer to just hide it from the response altogether.
An interesting one is the bool
field, as false
is the default value. I have been caught out before where I have setup my default value handling to ignore and consequently hidden any default values with my main aim of keeping my responses lightweight and clean. However, it then hid any bool
fields that were intentionally set to false
that I needed to display.
The good news is that we can configure how we handle default and null values at multiple levels from a global setting right down to an individual field overriding any global setting. I will discuss how we do this further in the post.
Can we set our own default values?
Yes, we absolutely can. Let’s say we have an int
field that we are using as a counter. Rather than the default value always being 0
we want it to be 1
. We can do this using the the DefaultValueAttribute
.
namespace WebIllumination.Demo { #region Usings using System.ComponentModel; #endregion /// <summary> /// Test class /// </summary> public class Test { /// <summary> /// Number counter /// </summary> [DefaultValue(1)] public int NumberCounter { get; set; } } }
DefaultValueHandling
DefaultValueHandling
is the setting in Newtonsoft that allows us to configure how we want Newtonsoft to handle how we serialise or deserialise default values. The options available are:
Include
– if the value of the field in the response is the default value of the type then it will still be included in the JSON response.Ignore
– if the value is the default value it will be ignored and the field will not be displayed in the JSON response.Populate
– this is used when deserialising and will set the value to the default value if the field is not included.IgnoreAndPopulate
– when serialising if the value is the default it will be ignored and the field not displayed. When deserialising the default value will be used if the field is not included.
Null values
Null values are much simpler than the default values as we are only dealing with how to handle the value if it is null. We have the option to either include the field or ignore it in our JSON responses.
NullValueHandling
NullValueHandling
is the setting in Newtonsoft that allows us to configure how we want Newtonsoft to handle how we serialise or deserialise null values. The options available are:
Include
– if the value is null it will be included and displayed in the JSON when both serialising and deserialising.Ignore
– if the value is null it will be ignored and hidden in the JSON when both serialising and deserialising.
Configure the default and null value handling
There are three main places (not limited to) where we can configure how Newtonsoft should handle the default and null values using the DefaultValueHandling
and NullValueHandling
settings:
- Globally
- On the field
- In the serialisation or deserialisation
Globally
In your project startup (Startup.cs
) you can configure how Newtonsoft should use these default settings through the AddMvc
option in the ConfigureServices
method.
/// <summary> /// Configure the services. /// </summary> /// <param name="services">The services collecton.</param> public void ConfigureServices(IServiceCollection services) { ... services.AddMvc() .AddJsonOptions(options => { options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Include; options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); ... }
On the field
You can add these settings directly on to a field and these will override any settings set at a global level.
namespace WebIllumination.Demo { #region Usings using Newtonsoft.Json; #endregion /// <summary> /// Test class /// </summary> public class Test { /// <summary> /// Number counter /// </summary> [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)] public int NumberCounter { get; set; } } }
In the serialisation or deserialisation
You can set how the default and null values are handled directly when you want to serialise or deserialise an object.
string jsonOutput = JsonConvert.SerializeObject(testObject, Formatting.Indented, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore });
References
- https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table
- https://www.newtonsoft.com/json/help/html/N_Newtonsoft_Json.htm
- https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.defaultvalueattribute?view=netcore-2.2
Add comment