ZetCode

C# JSON

last modified March 25, 2021

C# JSON tutorial shows how to work JSON data in C# using the classes of the standard library.

JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easily read and written by humans and parsed and generated by machines. The application/json is the official Internet media type for JSON. The JSON filename extension is .json.

In this tutorial, we work with the C# standard library. There is also a popular third-party library called Json.NET.

System.Text.Json

The System.Text.Json namespace provides high-performance, low-allocating, and standards-compliant tools to work with JSON. The classes allow us to serialize objects into JSON text and deserialize JSON text to objects. The UTF-8 support is built-in.

C# JSON parse

The JsonDocument.Parse parses a stream as UTF-8-encoded data representing a single JSON value into a JsonDocument. The stream is read to completion.

Program.cs
using System;
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.

using JsonDocument doc = JsonDocument.Parse(data);

We parse the JSON string into a JsonDocument.

JsonElement root = doc.RootElement;

We get the reference to the root element with the RootElement property.

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.

Console.WriteLine(u1.GetProperty("name"));
Console.WriteLine(u1.GetProperty("occupation"));

We get the properties of an element with GetProperty.

$ 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

The JsonElement.EnumerateArray enumerates the values in the JSON array represented by a JsonElement.

Program.cs
using System;
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}");
    }
}

In the example, we enumerate the contents of the root element.

var users = root.EnumerateArray();

We get the array of subelements.

while (users.MoveNext())
{
    var user = users.Current;
    Console.WriteLine(user);
...

In a while loop, we go over the array of elements.

var props = user.EnumerateObject();

while (props.MoveNext())
{
    var prop = props.Current;
    Console.WriteLine($"{prop.Name}: {prop.Value}");
}

In the second while loop, we go over the properties of each element.

$ 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

The JsonSerializer.Serialize converts the value of a specified type into a JSON string.

Program.cs
using System;
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);

In the example, we convert a User object into a JSON string.

$ dotnet run
{"Name":"John Doe","Occupation":"gardener",
    "DateOfBirth":{"year":1995,"month":11,"day":30}}

C# JSON deserialize

The JsonSerializer.Deserialize parses the text representing a single JSON value into an instance of a specified type.

Program.cs
using System;
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.

C# JSON create object

The Utf8JsonWriter provides a high-performance API for forward-only, non-cached writing of UTF-8 encoded JSON text.

Program.cs
using System;
using System.IO;
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);

In the example, we create a new object and write it into a JSON string.

$ dotnet run
{"name":"John Doe","occupation":"gardener","age":34}

C# beautify JSON

We can set the Indented option to true to beautify the JSON output.

Program.cs
using System.IO;
using System.Text.Json;

string data = " [ {\"name\": \"John Doe\", \"occupation\": \"gardener\"}, " +
    "{\"name\": \"Peter Novak\", \"occupation\": \"driver\"} ]";

JsonDocument jdoc = JsonDocument.Parse(data);

var fileName = @"/home/user7/data.json";
using FileStream fs = File.OpenWrite(fileName);

using var writer = new Utf8JsonWriter(fs, new JsonWriterOptions { Indented = true });
jdoc.WriteTo(writer);

In the example, we write a JSON string into a file. The data is prettified.

$ cat /home/user7/data.json 
[
    {
    "name": "John Doe",
    "occupation": "gardener"
    },
    {
    "name": "Peter Novak",
    "occupation": "driver"
    }
]

C# JSON Utf8JsonReader

The Utf8JsonReader orovides a high-performance API for forward-only, read-only access to UTF-8 encoded JSON text.

Program.cs
using System;
using System.IO;
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();

    }
}

In the example, we read JSON data from a file with Utf8JsonReader. It provides a low-level API for reading JSON data. We read the data token by token.

$ dotnet run
-------------
name: John Doe
occupation: gardener
-------------
name: Peter Novak
occupation: driver

C# JSON parse async

In the following example, we read a stream asynchronously with JsonDocument.ParseAsync.

Program.cs
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

using var httpClient = new HttpClient();
using var releasesResponse = await JsonDocument.ParseAsync(await httpClient.GetStreamAsync(
    "https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases-index.json"));

var root = releasesResponse.RootElement.GetProperty("releases-index");

var elems = root.EnumerateArray();
    
while (elems.MoveNext())
{
    var node = elems.Current;
    Console.WriteLine(node);
}

The example reads all releases of the .NET Core framework, which are available as a JSON string on the project Github repository.

In this tutorial, we have worked with JSON data in C#.

Read C# tutorial or list all C# tutorials.