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.

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

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 IgnorePropertiesResolverclass 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 Movieclass:

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.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!