Serialize and Deserialize JSON in C# with System.Text.Json

This guide explains how to serialize and deserialize JSON data in C# using the built-in System.Text.Json namespace. You will learn how to convert C# objects into JSON strings, parse JSON strings back into strongly typed objects, and configure common serialization options such as indentation and case sensitivity.

Prerequisites

To use System.Text.Json, include the namespace at the top of your C# file:

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

It is built into modern .NET (.NET Core 3.0 and later, .NET 6, 7, 8, and beyond).


Defining a Sample Model

Consider the following class used for the examples:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

How to Serialize an Object to JSON

Serialization converts a C# object into a JSON-formatted string using JsonSerializer.Serialize().

Basic Serialization

var user = new User
{
    Id = 1,
    Name = "Jane Doe",
    Email = "jane.doe@example.com"
};

string jsonString = JsonSerializer.Serialize(user);
Console.WriteLine(jsonString);
// Output: {"Id":1,"Name":"Jane Doe","Email":"jane.doe@example.com"}

Pretty Printing (Indented JSON)

To format the output with indentation and whitespace, pass an instance of JsonSerializerOptions:

var options = new JsonSerializerOptions { WriteIndented = true };
string formattedJson = JsonSerializer.Serialize(user, options);

How to Deserialize JSON to an Object

Deserialization converts a JSON string back into a C# object using JsonSerializer.Deserialize<T>().

Basic Deserialization

string jsonInput = "{\"Id\":1,\"Name\":\"Jane Doe\",\"Email\":\"jane.doe@example.com\"}";

User user = JsonSerializer.Deserialize<User>(jsonInput);

Console.WriteLine($"User: {user.Name} ({user.Email})");

Case-Insensitive Property Matching

By default, System.Text.Json requires property names to match exact casing (PascalCase). If your JSON uses camelCase or mixed case, enable PropertyNameCaseInsensitive:

string camelCaseJson = "{\"id\":1,\"name\":\"Jane Doe\",\"email\":\"jane.doe@example.com\"}";

var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};

User user = JsonSerializer.Deserialize<User>(camelCaseJson, options);

Customizing Properties with Attributes

You can control property behavior directly on your class definitions:

  • [JsonPropertyName]: Maps a property to a specific JSON key name.
  • [JsonIgnore]: Excludes a property from being serialized or deserialized.
public class User
{
    [JsonPropertyName("user_id")]
    public int Id { get; set; }

    public string Name { get; set; }

    [JsonIgnore]
    public string InternalNotes { get; set; }
}

Async Serialization with Streams

For web applications or large datasets, use asynchronous stream methods to optimize memory usage:

// Writing directly to a stream
using FileStream createStream = File.Create("user.json");
await JsonSerializer.SerializeAsync(createStream, user);

// Reading directly from a stream
using FileStream openStream = File.OpenRead("user.json");
User loadedUser = await JsonSerializer.DeserializeAsync<User>(openStream);