Lesson 30: Advanced JSON Processing with System.Text.Json
Serialise, deserialise, and customise JSON processing using .NET's built-in high-performance JSON library.
What You'll Learn
- • Serialize and deserialize objects with JsonSerializer
- • Control JSON output with attributes and JsonSerializerOptions
- • Write custom JsonConverter<T> for special types
- • Parse dynamic JSON with JsonDocument and Utf8JsonWriter
🧠 Real-World Analogy
JSON serialization is like translating between languages. Your C# objects speak "C#" and APIs speak "JSON." System.Text.Json is the translator — and a fast one, built into .NET with no extra dependencies.
Serialize & Deserialize
JsonSerializer.Serialize() converts C# objects to JSON strings, and Deserialize<T>() does the reverse. Use JsonSerializerOptions to control formatting, naming policies, and null handling. Attributes like [JsonIgnore] and [JsonPropertyName] give fine-grained control per property.
Serialize & Deserialize Objects
Convert C# objects to JSON and back with custom options and attributes.
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
// Model classes
class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public decimal Price { get; set; }
public string[] Tags { get; set; } = Array.Empty<string>();
[JsonIgnore] // Exclude from JSON
public string InternalCode { get; set; } = "";
[JsonPropertyName("is_available")] // Custom JSON name
public bool IsAvailable { get; set; }
}
class P
...Custom Converters
When the default serialization doesn't match your API format (e.g., Unix timestamps instead of ISO dates), write a JsonConverter<T>. Apply it per-property with [JsonConverter] or globally via options.
Custom JsonConverter — Unix Timestamps
Write a converter that serializes DateTime as Unix epoch seconds.
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
// Custom converter for special serialization logic
class UnixDateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type type,
JsonSerializerOptions options)
{
long unixTime = reader.GetInt64();
return DateTimeOffset.FromUnixTimeSeconds(unixTime).DateTime;
}
public override void Write(Utf8JsonWriter writer, DateTime value,
...JsonDocument & Utf8JsonWriter
When you don't have (or don't want) a C# model, JsonDocument parses JSON into a read-only DOM with minimal allocations. For building JSON from scratch, Utf8JsonWriter writes directly to a stream — perfect for high-throughput scenarios.
JsonDocument & Utf8JsonWriter
Parse dynamic JSON and build JSON manually with low-level writers.
using System;
using System.Text.Json;
class Program
{
static void Main()
{
// JsonDocument — read-only, low-allocation JSON parsing
string json = """
{
"users": [
{ "name": "Alice", "age": 30, "roles": ["admin", "user"] },
{ "name": "Bob", "age": 25, "roles": ["user"] },
{ "name": "Charlie", "age": 35, "roles": ["moderator", "user"] }
],
"total": 3,
"page": 1
}
...| Approach | Best For | Allocations |
|---|---|---|
| JsonSerializer | Known types, DTOs, APIs | Medium |
| JsonDocument | Dynamic/unknown JSON, read-only | Low |
| Utf8JsonWriter | Building JSON from scratch | Very Low |
| JsonNode | Read-write dynamic JSON | Medium |
Pro Tip
In .NET 8+, use [JsonSerializable] source generators for AOT-compatible, zero-reflection serialization. This eliminates all runtime reflection overhead and enables trimming.
Common Mistakes
- • Not disposing
JsonDocument— it pools memory internally - • Creating new
JsonSerializerOptionsevery call — cache and reuse them - • Forgetting case sensitivity — System.Text.Json is case-sensitive by default
Lesson Complete!
You've mastered JSON processing in .NET. Next, build REST APIs with ASP.NET Core.
Sign up for free to track which lessons you've completed and get learning reminders.