JSON Serialization and Deserialization with System.Text.Json

alex zhaoalex zhao
4 min read

Everyone knows how to use JSON serialization and deserialization with System.Text.Json, but most people use it somewhat vaguely. This article aims to help you understand and master System.Text.Json clearly, because...

"Clarity" is the sign that knowledge has truly been learned and internalized. ๐Ÿ˜Š


Why System.Text.Json? ๐Ÿ˜Š

There are many excellent open-source JSON libraries in .NET, such as Newtonsoft.Json. So, why should we use System.Text.Json?

Because:

  • It's officially provided by Microsoft and built into .NET Core 3.0+; all modern Microsoft code uses System.Text.Json, so understanding it is important!

  • High performance and low memory allocation, as stated in official documentation.

  • Thread-safe by design.

Terminology:

  • Serialization: Converting an object into a string (i.e., Object โ†’ string)

  • Deserialization: Converting a string into an object (i.e., string โ†’ Object)


Namespaces Involved ๐Ÿš€๐Ÿš€

  • System.Text.Json: The core namespace that provides classes like JsonSerializer for serialization/deserialization.

  • System.Text.Json.Serialization: Provides attributes such as [JsonPropertyName], and extensions for JsonSerializerOptions.

  • System.Net.Http.Json: Used with HttpClient to deserialize responses conveniently when making HTTP calls.


Basic Usage (Serialization / Deserialization) ๐ŸŽ‰๐ŸŽ‰

โœ… Serialization

Use JsonSerializer.Serialize() or its generic overload JsonSerializer.Serialize<T>(). Async versions are also available.

using demo;
using System.Text.Json;
using System.Text.Json.Serialization;

var person = new Person("John Doe", 30, true, new DateTime(1993, 5, 15));

var jsonString = JsonSerializer.Serialize(person);
var jsonString2 = JsonSerializer.Serialize<Person>(person);

Console.WriteLine(jsonString);
Console.WriteLine(jsonString2);

// Output: {"Name":"John Doe","Age":30,"IsStudent":true,"Birthday":"1993-05-15T00:00:00"}

โš ๏ธ Note: By default, the JSON output is minified (no indentation, newlines, or extra whitespace), which can be hard to read in logs. You can configure this with JsonSerializerOptions, which we'll cover below.


โœ… Deserialization

Use JsonSerializer.Deserialize() or JsonSerializer.Deserialize<T>(). Async versions are also available.

using demo;
using System.Text.Json;
using System.Text.Json.Serialization;

var jsonString = """
    {"Date":"2025-06-23T01:11:58.4217508+08:00","TemperatureCelsius":25,"Summary":"Sunny","Wind":10}
""";
var jsonObject = JsonSerializer.Deserialize<WeatherForecast>(jsonString);

Console.WriteLine(jsonObject?.Date);
Console.WriteLine(jsonObject?.TemperatureCelsius);
Console.WriteLine(jsonObject?.Summary);
Console.WriteLine(jsonObject?.WindSpeed);

Controlling Serialization / Deserialization Behavior ๐Ÿš€๐Ÿš€

What does it mean to "control behavior"? ๐Ÿ˜‚

For example: When building frontend-backend applications, frontend field names are usually camelCase, while C# uses PascalCase. So we often need to convert property names โ€” this requires customization of serialization behavior.

Another example: By default, System.Text.Json only serializes/deserializes public properties โ€” not fields. If you want to include fields, you need to configure that explicitly.


There are two main ways to control serialization behavior:

  1. Using attributes like [JsonPropertyName], [JsonIgnore], [JsonInclude]

  2. Using the JsonSerializerOptions class

Note 1: Both attributes and JsonSerializerOptions can influence behavior. Attributes are better for per-property control, while JsonSerializerOptions is ideal for global or complex configuration.

Note 2: Attributes take precedence over settings in JsonSerializerOptions.


๐Ÿ”ง JsonSerializerOptions

๐Ÿ”ธ Custom Property Naming

using demo;
using System.Text.Json;
using System.Text.Json.Serialization;

var weather = new WeatherForecast()
{
    Date = DateTimeOffset.Now,
    TemperatureCelsius = 25,
    Summary = "Sunny",
    WindSpeed = 10
};

var jsonoptions = new JsonSerializerOptions
{
   PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};

var json = JsonSerializer.Serialize(weather, jsonoptions);
Console.WriteLine(json);

๐Ÿ“ค Output:

{"date":"2025-06-23T02:04:44.6282091+08:00","temperatureCelsius":25,"summary":"Sunny","Wind":10}

โœ… All property names are now in camelCase, as typically expected in web APIs.


๐Ÿ”ธ Built-in Naming Policies

Naming PolicyDescriptionOriginalConverted
CamelCaseFirst word lowercase, subsequent words capitalizedTempCelsiustempCelsius
KebabCaseLowerLowercase words separated by hyphensTempCelsiustemp-celsius
KebabCaseUpperUppercase words separated by hyphensTempCelsiusTEMP-CELSIUS
SnakeCaseLowerLowercase words separated by underscoresTempCelsiustemp_celsius
SnakeCaseUpperUppercase words separated by underscoresTempCelsiusTEMP_CELSIUS

๐Ÿ”ธ Pretty Print / Human-Friendly Output

var jsonoptions = new JsonSerializerOptions
{
    WriteIndented = true
};

var json = JsonSerializer.Serialize(weather, jsonoptions);
Console.WriteLine(json);

๐Ÿงพ Output:

{
  "Date": "2025-06-23T02:10:26.5399846+08:00",
  "TemperatureCelsius": 25,
  "Summary": "Sunny",
  "Wind": 10
}

Much easier to read in logs or console compared to minified one-liner JSON.


๐Ÿ”ธ Ignoring Properties (Exclude from Serialization)

public class WeatherForecastWithIgnoreAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }

    [JsonIgnore]
    public string? Summary { get; set; }
}

๐Ÿ“ค Output:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25
  // "Summary" is missing
}

๐Ÿ”ธ Including Fields (Fields are not serialized by default)

// 1. Use attribute-based inclusion
public class Forecast2
{
    [JsonInclude]
    public DateTime Date;

    [JsonInclude]
    public int TemperatureC;

    [JsonInclude]
    public string? Summary;
}

// 2. Or globally allow fields via JsonSerializerOptions.IncludeFields

๐Ÿ“š Further Learning ๐ŸŽ‰๐ŸŽ‰

For more details, refer to the official Microsoft documentation: ๐Ÿ‘‰ .NET JSON serialization and deserialization

1
Subscribe to my newsletter

Read articles from alex zhao directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

alex zhao
alex zhao

full-stack developer,Cat Lovers