C# JSON

By FoxLearn 12/14/2024 2:40:38 AM   93
In C#, you can work with JSON using libraries such as Newtonsoft.Json or the built-in System.Text.Json in .NET Core.

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.