In this article, we are going to learn how to exclude properties from JSON serialization using the two most prominent JSON libraries for .NET. The libraries are System.Text.Json
, which has been natively available in the framework since .NET Core 3.0, and Newtonsoft.Json
.
A common problem that we found when serializing objects to JSON is that it ends up containing a lot of unwanted properties. By default, we can serialize all properties. However, so many times we don’t need all the information on the client, ending up consuming more bandwidth than necessary.
Let’s start.
Preparation
For this article, we are going to use a simple console application in .NET 7 version and install the Newtonsoft.Json
library through the NuGet Package Manager Console
:
PM> Install-Package Newtonsoft.Json
To print formatted results, we are going to use the WriteIndented
option from System.Text.Json
and the Formatting.Indented
from the Newtonsoft.Json
library:
JsonSerializer.Serialize(..., new JsonSerializerOptions { WriteIndented = true } ); JsonConvert.SerializeObject(..., Formatting.Indented );
To learn more about how to serialize objects, you can read How to Turn a C# Object Into a JSON String in .NET.
Ignore Individual Properties
Let’s assume we have a class with properties that we don’t need to include during serialization. For this, we can use the [JsonIgnore]
attribute on the property to ensure that this value is not included during object serialization. The attribute is available in the System.Text.Json.Serialization
namespace.
For example, let’s create a Person
class:
public class Person { [JsonIgnore] public int Id { get; set; } public string? Name { get; set; } public string? LastName { get; set; } }
In our Program
class, let’s serialize the Person
object through the System.Text.Json
library:
var person = new Person() { Id = 1, Name = "John", LastName = "Smith" }; var json = JsonSerializer.Serialize(person, new JsonSerializerOptions { WriteIndented = true } ); Console.WriteLine(json);
In the output, we have our serialized object, but without the properties marked with [JsonIgnore]
:
{ "Name": "John", "LastName": "Smith" }
To perform serialization with the Newtonsoft.Json
library, we need to change the [JsonIgnore]
attribute in the Person
class to make use of the Newtonsoft.Json
namespace and then we can serialize the object:
var json = JsonConvert.SerializeObject(person, Formatting.Indented ); Console.WriteLine(json);
As with the serialization with the previous library, our serialized object did not have the ignored properties:
{ "Name": "John", "LastName": "Smith" }
DataContract and DataMember Attributes
In some scenarios, we have classes with many properties and we want to serialize only some of them. To reduce this effort, we can use the [DataContract]
class attribute, and for the properties that must remain in the serialization, we need to use the [DataMember]
attribute. Both are available in the System.Runtime.Serialization
namespace. This is opt-in serialization, only the properties we mark it with will be serialized. These attributes are used to replace ones from Newtonsoft.Json
.
Let’s create a Customer
class:
[DataContract] public class Customer { public int Id { get; set; } [DataMember] public string? Name { get; set; } [DataMember] public string? LastName { get; set; } }
To serialize an object of the created class, let’s run the code:
var customer = new Customer() { Id = 1, Name = "John", LastName = "Smith" }; var json = JsonConvert.SerializeObject(customer, Formatting.Indented ); Console.WriteLine(json);
And the output will be:
{ "Name": "John", "LastName": "Smith" }
As we can see, only properties marked with the [DataMember]
attribute were serialized.
Ignore All Null-Value Properties
Another scenario we can consider is to remove all null properties from the serialization, but without needing to add the [JsonIgnore]
attribute to each one.
First, let’s declare the Book
class:
public class Book { public int Id { get; set; } public string? Title { get; set; } public int? Pages { get; set; } public int Sells { get; set; } public Author? Author { get; set; } }
Now let’s create an instance of JsonSerializerOptions
from the System.Text.Json
library and set the DefaultIgnoreCondition
property to WhenWritingNull
:
var book = new Book() { Id = 1, Title = "Dracula" }; var json = JsonSerializer.Serialize(book, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, WriteIndented = true }); Console.WriteLine(json);
With Newtonsoft.Json
, we have a slightly different approach, we need to instantiate the JsonSerializerSettings
class and set the NullValueHandling
flag to Ignore
:
var json = JsonConvert.SerializeObject(book, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); Console.WriteLine(json);
And the output will be the same for both:
{ "Id": 1, "Title": "Dracula", "Sells": 0 }
Ignore All Default-Value Properties
Just as we can ignore all null properties, we can also ignore all properties that have a default value.
When we use JsonSerializerOptions
, we just change the DefaultIgnoreCondition
property to WhenWritingDefault
:
var book = new Book() { Id = 1, Title = "Dracula" }; var json = JsonSerializer.Serialize(book, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault, WriteIndented = true }); Console.WriteLine(json);
When using Newtonsoft.Json
we have to set the DefaultValueHandling
property of the JsonSerializerSettings
class to Ignore
:
var json = JsonConvert.SerializeObject(book, Formatting.Indented, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); Console.WriteLine(json);
The result is:
{ "Id": 1, "Title": "Dracula" }
And to be clear, when we ignore parameters with a default value, we end up ignoring properties with a null value and properties set to their default value (0 for int, false for bool, etc…).
Exclude Properties From JSON Using IContractResolver
For more flexibility, Newtonsoft.Json
provides the IContractResolver
interface to customize aspects of how a .NET object is serialized to JSON, including changing serialization behavior at runtime.
For example, let’s define a IgnorePropertiesResolver
class that inherits from DefaultContractResolver
:
public class IgnorePropertiesResolver : DefaultContractResolver { private readonly HashSet<string> _ignoreProps; public IgnorePropertiesResolver(params string[] propNamesToIgnore) { _ignoreProps = new HashSet<string>(propNamesToIgnore); } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); if (_ignoreProps.Contains(property.PropertyName)) { property.ShouldSerialize = _ => false; } return property; } }
Through the created class, we can inform all the fields that we don’t want to serialize at runtime, by instantiating it in the ContractResolver
property of the JsonSerializerSettings
class.
To exemplify its use, let’s create a Movie
class:
public class Movie { public int Id { get; set; } public string? Name { get; set; } public string? Description { get; set; } public int Classification { get; set; } }
And then we make use of the resolver:
var movie = new Movie() { Id = 1, Name = "Titanic", Classification = 12, Description = "It is based on accounts of the sinking of the RMS Titanic" }; var json = JsonConvert.SerializeObject(movie, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new IgnorePropertiesResolver("Id", "Classification") }); Console.WriteLine(json);
The output is:
{ "Name": "Titanic", "Description": "It is based on accounts of the sinking of the RMS Titanic" }
Conditional Ignore Individual Properties
In addition to the options shown, we can also apply conditions when individually ignoring a property. By doing this, we’ll override the serializer’s default setting for this property. We can specify conditional exclusion by setting the Condition property of the [JsonIgnore]
attribute. For the Newtonsoft.Json
, we can individually customize the properties using the JsonPropertyAttribute.
Conclusion
In this article, we discussed how to exclude properties from JSON serialization for both the System.Text.Json
and Newtonsoft.Json
libraries. We showed how to ignore individually a property, as well as more generally ignoring via the serialization options. We also saw that the libraries have slight differences, so rate the use of each one and choose the one that best fits your use.