C# JSON
last modified July 5, 2023
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 article 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.
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
.
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.
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.
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# JsonSerializerOptions
With JsonSerializerOptions
, we can control the process of
serialization with some options.
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.
$ 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
The Utf8JsonWriter
provides a high-performance API for
forward-only, non-cached writing of UTF-8 encoded JSON text.
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}
We can set the Indented
option to true
to beautify
the JSON output.
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);
In the example, we write a JSON string into a file. The data is prettyfied.
$ cat 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.
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
.
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); }
The example reads all releases of the .NET Core framework, which are available as a JSON string on the project Github repository.
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.
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.
var data = await client.GetFromJsonAsync<Users>(url);
The GetFromJsonAsync
is a convenience method which transforms
JSON resource into C# collections.
class Users { public List<User> users { get; set; } = new(); }
We need to create a specific class for the List
collection.
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.
$ 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.