What is JSON?
JSON (JavaScript Object Notation) is a lightweight data format used for data interchange. It is human-readable and easy for machines to parse and generate. The official Internet media type for JSON is application/json
, and its file extension is .json
.
System.Text.Json
The System.Text.Json
namespace offers high-performance, low-allocation, and standards-compliant tools for working with JSON. It enables serialization of objects into JSON text and deserialization of JSON text into objects, with built-in support for UTF-8 encoding.
C# JSON parse
The JsonDocument
class, part of the System.Text.Json
namespace, provides a read-only, DOM-like approach to parse and work with JSON data. The JsonDocument.Parse
method parses a UTF-8-encoded stream representing a single JSON value into a JsonDocument
, reading the entire stream to completion.
For example, Parsing JSON and Accessing Values
static void Main(string[] args)
{
string jsonString = "{\"name\":\"John\",\"age\":30,\"isEmployed\":true}";
// Parse the JSON string into a JsonDocument
using (JsonDocument doc = JsonDocument.Parse(jsonString))
{
// Access the root element (which is a JSON object)
var root = doc.RootElement;
// Access individual properties
string name = root.GetProperty("name").GetString();
int age = root.GetProperty("age").GetInt32();
bool isEmployed = root.GetProperty("isEmployed").GetBoolean();
Console.WriteLine($"Name: {name}, Age: {age}, Employed: {isEmployed}");
}
}
Output:
Name: John, Age: 30, Employed: True
C# JSON enumerate
The JsonElement.EnumerateArray
method enumerates the values in a JSON array represented by a JsonElement
. This is particularly useful when working with JSON data that contains arrays, allowing you to iterate through each item.
static void Main(string[] args)
{
// Sample JSON array string
string jsonString = "[{\"name\":\"John\",\"age\":30}, {\"name\":\"Jane\",\"age\":25}, {\"name\":\"Alice\",\"age\":28}]";
// Parse the JSON string into a JsonDocument
using (JsonDocument doc = JsonDocument.Parse(jsonString))
{
// Enumerate through the JSON array
foreach (JsonElement element in doc.RootElement.EnumerateArray())
{
// Access the properties of each object in the array
string name = element.GetProperty("name").GetString();
int age = element.GetProperty("age").GetInt32();
// Output the results
Console.WriteLine($"Name: {name}, Age: {age}");
}
}
}
Output:
Name: John, Age: 30
Name: Jane, Age: 25
Name: Alice, Age: 28
C# JSON serialize
The JsonSerializer.Serialize
method converts the value of a specified type into a JSON string.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsEmployed { get; set; }
}
static void Main(string[] args)
{
// Create a sample object
var person = new Person
{
Name = "John",
Age = 30,
IsEmployed = true
};
// Serialize the object to JSON string
string jsonString = JsonSerializer.Serialize(person);
// Output the JSON string
Console.WriteLine(jsonString);
}
In the example, we convert a Person
object into a JSON string.
Output:
{"Name":"John","Age":30,"IsEmployed":true}
C# JSON deserialize
The JsonSerializer.Deserialize
method parses a JSON text representing a single JSON value and converts it into an instance of a specified type.
static void Main()
{
// JSON string to deserialize
string jsonString = "{\"Name\":\"John\",\"Age\":30,\"IsEmployed\":true}";
// Deserialize the JSON string into a Person object
Person person = JsonSerializer.Deserialize<Person>(jsonString);
// Output the deserialized object
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, Employed: {person.IsEmployed}");
}
The example parses the JSON string into an instance of the Person
type.
Output:
Name: John, Age: 30, Employed: True
C# JsonSerializerOptions
With JsonSerializerOptions
, you can control the serialization process by specifying various options, such as formatting, property naming policies, and handling of null values, among others.
For example, Using JsonSerializerOptions
for Pretty-Printing
static void Main()
{
var person = new Person
{
Name = "John",
Age = 30,
IsEmployed = true
};
// Configure JsonSerializerOptions to enable pretty-printing
var options = new JsonSerializerOptions
{
WriteIndented = true // Enable indentation
};
// Serialize the object with pretty-printing
string jsonString = JsonSerializer.Serialize(person, options);
// Output the formatted JSON string
Console.WriteLine(jsonString);
}
Output:
{
"Name": "John",
"Age": 30,
"IsEmployed": true
}
C# Utf8JsonWriter
The Utf8JsonWriter
provides a high-performance API for writing UTF-8 encoded JSON text in a forward-only, non-cached manner. It allows you to efficiently generate JSON output without needing to store it in memory all at once.
static void Main()
{
// Create a memory stream to hold the JSON data
using (MemoryStream stream = new MemoryStream())
{
// Create the Utf8JsonWriter
using (Utf8JsonWriter writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }))
{
// Start writing the JSON array
writer.WriteStartArray();
// Write elements to the array
writer.WriteStartObject();
writer.WriteString("Name", "John");
writer.WriteNumber("Age", 30);
writer.WriteEndObject();
writer.WriteStartObject();
writer.WriteString("Name", "Jane");
writer.WriteNumber("Age", 25);
writer.WriteEndObject();
// End the JSON array
writer.WriteEndArray();
}
// Convert the memory stream to a string
string jsonString = Encoding.UTF8.GetString(stream.ToArray());
// Output the JSON string
Console.WriteLine(jsonString);
}
}
Output:
[
{
"Name": "John",
"Age": 30
},
{
"Name": "Jane",
"Age": 25
}
]
C# JSON Utf8JsonReader
The Utf8JsonReader
provides a high-performance, forward-only, and read-only API for accessing UTF-8 encoded JSON text. It allows you to efficiently parse and read JSON data without storing the entire content in memory.
static void Main()
{
// Sample JSON string
string jsonString = "{\"Name\":\"John\", \"Age\":30, \"IsEmployed\":true}";
// Convert the JSON string to a byte array
byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString);
// Initialize the Utf8JsonReader
Utf8JsonReader reader = new Utf8JsonReader(jsonBytes);
// Parse the JSON
while (reader.Read())
{
// Check the current token type
switch (reader.TokenType)
{
case JsonTokenType.StartObject:
Console.WriteLine("Start of JSON Object");
break;
case JsonTokenType.PropertyName:
Console.WriteLine($"Property: {reader.GetString()}");
break;
case JsonTokenType.String:
Console.WriteLine($"String Value: {reader.GetString()}");
break;
case JsonTokenType.Number:
Console.WriteLine($"Number Value: {reader.GetInt32()}");
break;
case JsonTokenType.True:
case JsonTokenType.False:
Console.WriteLine($"Boolean Value: {reader.GetBoolean()}");
break;
case JsonTokenType.EndObject:
Console.WriteLine("End of JSON Object");
break;
}
}
}
Output:
Start of JSON Object
Property: Name
String Value: John
Property: Age
Number Value: 30
Property: IsEmployed
Boolean Value: True
End of JSON Object
C# JSON parse async
In the following example, we read a stream asynchronously using JsonDocument.ParseAsync
.
This method allows you to asynchronously parse JSON data from a stream, making it suitable for working with large JSON files or data streams without blocking the thread. ParseAsync
is useful for scenarios where you need to handle JSON data from file systems, HTTP responses, or other I/O-bound sources in an efficient, non-blocking way.
static async Task Main(string[] args)
{
// URL to fetch the JSON data
var url = "https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases-index.json";
// Use HttpClient to fetch the JSON data as a stream
using (var httpClient = new HttpClient())
{
var client = await httpClient.GetStreamAsync(url);
// Parse the JSON stream asynchronously
using (var response = await JsonDocument.ParseAsync(client))
{
// Get the root property (releases-index)
var root = response.RootElement.GetProperty("releases-index");
// Enumerate the array elements within "releases-index"
var elems = root.EnumerateArray();
// Loop through the elements and print each one
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's GitHub repository. It uses HttpClient
to asynchronously fetch the JSON data from the repository, and JsonDocument.ParseAsync
to parse the data. The parsed JSON is then processed by enumerating through the "releases-index" array, with each release printed to the console.
C# HttpClient GetFromJsonAsync
The GetFromJsonAsync
method sends a GET request to the specified URL and asynchronously deserializes the response body into a specified type. It automatically converts the JSON response into an object, making it easier to work with data retrieved from web APIs or other HTTP endpoints.
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
class Program
{
// Define a model that maps the JSON response
public class Person
{
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("age")]
public int Age { get; set; }
[JsonPropertyName("email")]
public string Email { get; set; }
}
static async Task Main(string[] args)
{
// Create an instance of HttpClient
using var httpClient = new HttpClient();
// Define the URL of the API
var url = "https://api.example.com/person/1"; // Replace with a real API URL
try
{
// Use GetFromJsonAsync to fetch and deserialize the JSON response into a Person object
var person = await httpClient.GetFromJsonAsync<Person>(url);
// Output the deserialized data
if (person != null)
{
Console.WriteLine($"ID: {person.Id}");
Console.WriteLine($"Name: {person.Name}");
Console.WriteLine($"Age: {person.Age}");
Console.WriteLine($"Email: {person.Email}");
}
else
{
Console.WriteLine("Failed to fetch person data.");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request error: {e.Message}");
}
}
}
We will create a model that matches this structure and use GetFromJsonAsync
to fetch and deserialize this data.