C# JSON
last modified May 13, 2025
This C# JSON tutorial demonstrates how to handle JSON data using the built-in classes of the standard library. JSON is a widely used data format for exchanging information between applications, especially in web development and APIs. Understanding how to parse, serialize, and manipulate JSON in C# is essential for building modern .NET applications that interact with external data sources or services.
JSON
JSON (JavaScript Object Notation) is a lightweight format for data exchange. It
is easy for humans to read and write while being efficiently parsed and
generated by machines. The official Internet media type for JSON is
application/json
, and JSON files typically use the
.json
extension. JSON supports basic data types such as strings,
numbers, booleans, arrays, and objects, making it flexible for representing
complex data structures.
In this tutorial, we focus on working with JSON using the C# standard library.
Additionally, there is a widely used third-party library called
Json.NET
, which offers extended functionality for JSON processing.
While System.Text.Json
is recommended for most new projects due to
its performance and integration with .NET, Json.NET
remains
popular for its advanced features and compatibility.
System.Text.Json
The System.Text.Json
namespace provides a high-performance,
memory-efficient, and standards-compliant solution for working with JSON in C#.
It supports serialization of objects into JSON text and deserialization of JSON
text into objects, with built-in UTF-8 optimization for faster processing.
This namespace is included in .NET Core 3.0 and later, and is the preferred
way to handle JSON in modern C# applications.
C# JSON parse
The JsonDocument.Parse
method parses a stream or string as
UTF-8-encoded data representing a single JSON value into a
JsonDocument
. The stream is read to completion, and the resulting
document provides a DOM-like API for navigating and extracting data from the
JSON structure. This is useful when you need to inspect or manipulate JSON
data without mapping it directly to C# types.
using System.Text.Json; string data = @" [ {""name"": ""John Doe"", ""occupation"": ""gardener""}, {""name"": ""Peter Novak"", ""occupation"": ""driver""} ]"; using JsonDocument doc = JsonDocument.Parse(data); JsonElement root = doc.RootElement; Console.WriteLine(root); var u1 = root[0]; var u2 = root[1]; Console.WriteLine(u1); Console.WriteLine(u2); Console.WriteLine(u1.GetProperty("name")); Console.WriteLine(u1.GetProperty("occupation")); Console.WriteLine(u2.GetProperty("name")); Console.WriteLine(u2.GetProperty("occupation"));
In the example, we parse a simple JSON string containing an array of objects.
Each object represents a user with a name and occupation. We use
JsonDocument
to parse the string and access the root element,
which is an array. We then extract individual elements and their properties
using the provided API. This approach is helpful when working with dynamic or
unknown JSON structures.
using JsonDocument doc = JsonDocument.Parse(data);
We parse the JSON string into a JsonDocument
, which allows us to
navigate the JSON structure using the DOM-like API. This is especially useful
when the structure of the JSON is not known at compile time or when you need
to access only a subset of the data.
JsonElement root = doc.RootElement;
We get the reference to the root element with the RootElement
property. The root element can be an object, array, or primitive value,
depending on the JSON data.
var u1 = root[0]; var u2 = root[1]; Console.WriteLine(u1); Console.WriteLine(u2);
With the []
operator, we get the first and the second subelements
of the JSON document. This allows us to access individual objects within the
array and further inspect their properties.
Console.WriteLine(u1.GetProperty("name")); Console.WriteLine(u1.GetProperty("occupation"));
We get the properties of an element with GetProperty
. This method
retrieves the value of a named property from a JSON object, enabling us to
extract specific fields from the data.
$ dotnet run [ {"name": "John Doe", "occupation": "gardener"}, {"name": "Peter Novak", "occupation": "driver"} ] {"name": "John Doe", "occupation": "gardener"} {"name": "Peter Novak", "occupation": "driver"} John Doe gardener Peter Novak driver
C# JSON enumerate
In the example, we enumerate the contents of the root element, which is a JSON
array. We use the EnumerateArray
method to iterate over each
object in the array, and then use EnumerateObject
to access all
properties of each object. This approach is useful for processing collections
of data in JSON format, such as lists of users or items.
using System.Text.Json; string data = @" [ {""name"": ""John Doe"", ""occupation"": ""gardener""}, {""name"": ""Peter Novak"", ""occupation"": ""driver""} ]"; using var doc = JsonDocument.Parse(data); JsonElement root = doc.RootElement; var users = root.EnumerateArray(); while (users.MoveNext()) { var user = users.Current; System.Console.WriteLine(user); var props = user.EnumerateObject(); while (props.MoveNext()) { var prop = props.Current; Console.WriteLine($"{prop.Name}: {prop.Value}"); } }
We get the array of subelements using EnumerateArray
. This method
returns an enumerator that allows us to loop through each element in the JSON
array, making it easy to process multiple items.
var users = root.EnumerateArray();
In a while loop, we go over the array of elements. For each element, we print the entire object and then enumerate its properties. This demonstrates how to traverse nested JSON structures and extract detailed information from each object.
while (users.MoveNext()) { var user = users.Current; Console.WriteLine(user); ...
In the second while loop, we go over the properties of each element. We use
EnumerateObject
to access all key-value pairs in the JSON object,
allowing us to print or process each property individually.
var props = user.EnumerateObject(); while (props.MoveNext()) { var prop = props.Current; Console.WriteLine($"{prop.Name}: {prop.Value}"); }
$ dotnet run {"name": "John Doe", "occupation": "gardener"} name: John Doe occupation: gardener {"name": "Peter Novak", "occupation": "driver"} name: Peter Novak occupation: driver
C# JSON serialize
In the example, we convert a User
object into a JSON string using
JsonSerializer.Serialize
. Serialization is the process of
converting an object or data structure into a format that can be easily stored
or transmitted, such as JSON. This is commonly used when sending data to web
APIs or saving configuration files.
using System.Text.Json; var user = new User("John Doe", "gardener", new MyDate(1995, 11, 30)); var json = JsonSerializer.Serialize(user); Console.WriteLine(json); record MyDate(int year, int month, int day); record User(string Name, string Occupation, MyDate DateOfBirth);
$ dotnet run {"Name":"John Doe","Occupation":"gardener", "DateOfBirth":{"year":1995,"month":11,"day":30}}
C# JSON deserialize
The JsonSerializer.Deserialize
method parses the text representing
a single JSON value into an instance of a specified type. This allows you to
convert JSON data received from external sources into strongly-typed C#
objects, making it easier to work with the data in your application.
using System.Text.Json; string json = @"{""Name"":""John Doe"", ""Occupation"":""gardener"", ""DateOfBirth"":{""year"":1995,""month"":11,""day"":30}}"; var user = JsonSerializer.Deserialize<User>(json); Console.WriteLine(user); Console.WriteLine(user?.Name); Console.WriteLine(user?.Occupation); Console.WriteLine(user?.DateOfBirth); record MyDate(int year, int month, int day); record User(string Name, string Occupation, MyDate DateOfBirth);
The example parses the JSON string into an instance of the User
type. After deserialization, you can access the properties of the object as
you would with any C# class, enabling type-safe manipulation of the data.
C# JsonSerializerOptions
With JsonSerializerOptions
, we can control the process of
serialization with some options. For example, the WriteIndented
option enables pretty printing, making the output more readable. Other options
allow customization of property naming, handling of null values, and more.
using System.Text.Json; var words = new Dictionary<int, string> { {1, "sky"}, {2, "cup"}, {3, "odd"}, {4, "cloud"}, {5, "forest"}, {6, "warm"}, }; var r = JsonSerializer.Serialize(words, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(r); Console.WriteLine("---------------------"); var d = JsonSerializer.Deserialize<Dictionary<int, string>>(r); foreach (var (k, v) in d!) { Console.WriteLine($"{k}: {v}"); }
With the WriteIndented
option set, we enable indentation for
pretty printing. This is useful for debugging or when the JSON output needs to
be human-readable, such as in configuration files or logs.
$ dotnet run { "1": "sky", "2": "cup", "3": "odd", "4": "cloud", "5": "forest", "6": "warm" } --------------------- 1: sky 2: cup 3: odd 4: cloud 5: forest 6: warm
C# Utf8JsonWriter
In the example, we create a new object and write it into a JSON string using
Utf8JsonWriter
. This class provides a high-performance, forward-
only API for writing UTF-8 encoded JSON text. It is suitable for scenarios
where you need to generate JSON dynamically or with fine-grained control over
the output.
using System.Text.Json; using System.Text; using var ms = new MemoryStream(); using var writer = new Utf8JsonWriter(ms); writer.WriteStartObject(); writer.WriteString("name", "John Doe"); writer.WriteString("occupation", "gardener"); writer.WriteNumber("age", 34); writer.WriteEndObject(); writer.Flush(); string json = Encoding.UTF8.GetString(ms.ToArray()); Console.WriteLine(json);
$ dotnet run {"name":"John Doe","occupation":"gardener","age":34}
In the example, we write a JSON string into a file. The data is prettyfied
using the Indented
option of JsonWriterOptions
.
Pretty printing makes the JSON easier to read and maintain, especially for
configuration files or data meant for manual inspection.
using System.Text.Json; string data = @" [ {""name"": ""John Doe"", ""occupation"": ""gardener""}, {""name"": ""Peter Novak"", ""occupation"": ""driver""} ]"; JsonDocument jdoc = JsonDocument.Parse(data); var fileName = @"data.json"; using FileStream fs = File.OpenWrite(fileName); using var writer = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true }); jdoc.WriteTo(writer);
$ cat data.json [ { "name": "John Doe", "occupation": "gardener" }, { "name": "Peter Novak", "occupation": "driver" } ]
C# JSON Utf8JsonReader
In the example, we read JSON data from a file with Utf8JsonReader
.
It provides a low-level API for reading JSON data token by token. This is
useful for processing large JSON files or streams efficiently, as it avoids
loading the entire document into memory.
using System.Text.Json; var fileName = @"/home/user7/data.json"; byte[] data = File.ReadAllBytes(fileName); Utf8JsonReader reader = new Utf8JsonReader(data); while (reader.Read()) { switch (reader.TokenType) { case JsonTokenType.StartObject: Console.WriteLine("-------------"); break; case JsonTokenType.EndObject: break; case JsonTokenType.StartArray: case JsonTokenType.EndArray: break; case JsonTokenType.PropertyName: Console.Write($"{reader.GetString()}: "); break; case JsonTokenType.String: Console.WriteLine(reader.GetString()); break; default: throw new ArgumentException(); } }
$ dotnet run ------------- name: John Doe occupation: gardener ------------- name: Peter Novak occupation: driver
C# JSON parse async
The example reads all releases of the .NET Core framework, which are available
as a JSON string on the project Github repository. It demonstrates how to use
JsonDocument.ParseAsync
to read and parse JSON data from a stream
asynchronously, which is important for responsive applications that handle
network or file I/O.
using System.Text.Json; using var httpClient = new HttpClient(); var url = "https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases-index.json"; var ts = await httpClient.GetStreamAsync(url); using var resp = await JsonDocument.ParseAsync(ts); var root = resp.RootElement.GetProperty("releases-index"); var elems = root.EnumerateArray(); while (elems.MoveNext()) { var node = elems.Current; Console.WriteLine(node); }
C# HttpClient GetFromJsonAsync
The GetFromJsonAsync
method sends a GET request to the specified
URL and returns the value that results from deserializing the response body as
JSON in an asynchronous operation. This method simplifies the process of
fetching and parsing JSON data from web APIs, making it easy to integrate
external data sources into your C# applications.
The method is an extension method from System.Net.Http.Json
.
using System.Text.Json.Serialization; using System.Net.Http.Json; using var client = new HttpClient(); var url = "http://webcode.me/users.json"; var data = await client.GetFromJsonAsync<Users>(url); if (data != null) { foreach (var user in data.users) { Console.WriteLine(user); } } class Users { public List<User> users { get; set; } = new(); } class User { [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("first_name")] public string FirstName { get; set; } = string.Empty; [JsonPropertyName("last_name")] public string LastName { get; set; } = string.Empty; [JsonPropertyName("email")] public string Email { get; set; } = string.Empty; public override string ToString() { return $"User {{ {Id}| {FirstName} {LastName}| {Email} }}"; } }
We create an asynchronous http request to a JSON resource. The JSON data is
serialized into a list of User
objects, allowing for easy
iteration and processing of the data in C#.
var data = await client.GetFromJsonAsync<Users>(url);
The GetFromJsonAsync
is a convenience method which transforms
JSON resource into C# collections. It handles the HTTP request, response,
deserialization, and error handling, reducing boilerplate code and improving
productivity.
class Users { public List<User> users { get; set; } = new(); }
We need to create a specific class for the List
collection. This
class acts as a container for the deserialized data, matching the structure of
the JSON response.
class User { [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("first_name")] public string FirstName { get; set; } = string.Empty; [JsonPropertyName("last_name")] public string LastName { get; set; } = string.Empty; [JsonPropertyName("email")] public string Email { get; set; } = string.Empty; public override string ToString() { return $"User {{ {Id}| {FirstName} {LastName}| {Email} }}"; } }
The JSON fields are mapped to class attributes using the
JsonPropertyName
attribute. This ensures that the C# properties
correspond to the correct JSON fields, even if the names differ. Overriding
ToString()
provides a convenient way to display the object data.
$ dotnet run User { 1| Robert Schwartz| rob23@gmail.com } User { 2| Lucy Ballmer| lucyb56@gmail.com } User { 3| Anna Smith| annasmith23@gmail.com } User { 4| Robert Brown| bobbrown432@yahoo.com } User { 5| Roger Bacon| rogerbacon12@yahoo.com }
Source
JSON serialization and deserialization
In this article we have worked with JSON data in C#.
Author
List all C# tutorials.