How to exclude a property from being serialized in System.Text.Json.JsonSerializer.Serialize() using a JsonConverter

Option 1 - Cast to Interface

  1. Extract interface which describes structure of desired object.

    public interface IBook
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
  2. Implement it on the original class class Book : IBook

  3. Use the follow overload of string Serialize(object value, Type inputType, JsonSerializerOptions options = null);

    json = JsonSerializer.Serialize(book, typeof(IBook), options);
    

    If you're serializing array of Books (plural), you'll need to pass typeof(IEnumerable<IBook>) as an argument.

Option 2 - Use AutoMapper

This is useful if you don't have access to the original Book class.

  1. Create LiteBook class:

    public class LiteBook
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
  2. Create mapping configuration:

    var config = new MapperConfiguration(cfg => {
        cfg.CreateMap<Book, LiteBook>();
    });
    
  3. Map it and serialize

    json = JsonSerializer.Serialize(new Mapper(config).Map<LiteBook>(book), options)
    

So I happened to stumble upon an article that demonstrates how to use the JsonDocument object in the new System.Text.Json namespace and it is the next best thing to a Fluent API. Here is how this question can be solved.

The BookConverter.Write() method:

public override void Write(Utf8JsonWriter writer, Book value, JsonSerializerOptions options)
{
    writer.WriteStartObject();

    using (JsonDocument document = JsonDocument.Parse(JsonSerializer.Serialize(value)))
    {
        foreach (var property in document.RootElement.EnumerateObject())
        {
            if (property.Name != "Author")
                property.WriteTo(writer);
        }
    }

    writer.WriteEndObject();
}