C# -

JSON Handling

JSON (JavaScript Object Notation) is a lightweight data-interchange format that's easy for humans to read and write and easy for machines to parse and generate. This tutorial covers the basics, advanced concepts, and best practices for handling JSON in C#.


1. Introduction to JSON Handling

JSON is commonly used for data interchange between client and server applications. C# provides robust libraries to parse, generate, and manipulate JSON data.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"John\",\"Age\":30}";
        var person = JsonConvert.DeserializeObject<dynamic>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
    }
}
        
    

In this example, we introduce the basics of JSON handling in C#.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"Jane\",\"Age\":25}";
        var person = JsonSerializer.Deserialize<dynamic>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
    }
}
        
    

Here, we further explore JSON handling with a more complex example.


2. Parsing JSON Strings

Parsing JSON strings into C# objects is a fundamental operation. Here's how you can parse a JSON string using Newtonsoft.Json.

        
            using System;
using Newtonsoft.Json.Linq;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"John\",\"Age\":30}";
        var jsonObject = JObject.Parse(jsonString);
        Console.WriteLine($"Name: {jsonObject["Name"]}, Age: {jsonObject["Age"]}");
    }
}
        
    

This example shows basic parsing of a JSON string into a dynamic object.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"Jane\",\"Age\":25}";
        var person = JsonSerializer.Deserialize<Person>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
    }
}
        
    

This example demonstrates parsing a JSON string into a strongly-typed object.


3. Generating JSON Strings

Generating JSON strings from C# objects is equally important. Here's how you can convert an object to a JSON string.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var person = new { Name = "John", Age = 30 };
        var jsonString = JsonConvert.SerializeObject(person);
        Console.WriteLine(jsonString);
    }
}
        
    

This example illustrates converting a simple object to a JSON string.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person { Name = "Jane", Age = 25 };
        var jsonString = JsonSerializer.Serialize(person);
        Console.WriteLine(jsonString);
    }
}
        
    

This example demonstrates converting a more complex object, including nested objects, to a JSON string.


4. Using Newtonsoft.Json

Newtonsoft.Json (Json.NET) is a popular library for handling JSON in C#. It provides comprehensive support for JSON parsing and serialization.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"John\",\"Age\":30}";
        var person = JsonConvert.DeserializeObject<dynamic>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
    }
}
        
    

This example shows basic JSON handling using Newtonsoft.Json.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class CustomDateTimeConverter : JsonConverter<DateTime>
{
    public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString("yyyy-MM-dd"));
    }

    public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        return DateTime.Parse(reader.Value.ToString());
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person { Name = "Jane", Age = 25 };
        var settings = new JsonSerializerSettings();
        settings.Converters.Add(new CustomDateTimeConverter());
        var jsonString = JsonConvert.SerializeObject(person, settings);
        Console.WriteLine(jsonString);
    }
}
        
    

This example demonstrates more advanced features of Newtonsoft.Json, such as custom converters.


5. Using System.Text.Json

System.Text.Json is a high-performance JSON library introduced in .NET Core 3.0. It's a modern alternative to Newtonsoft.Json.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"John\",\"Age\":30}";
        var person = JsonSerializer.Deserialize<dynamic>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
    }
}
        
    

This example illustrates basic JSON handling using System.Text.Json.

        
            using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class CustomDateTimeConverter : JsonConverter<DateTime>
{
    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
    }

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.Parse(reader.GetString());
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        var options = new JsonSerializerOptions();
        options.Converters.Add(new CustomDateTimeConverter());

        var person = new Person { Name = "Jane", Age = 25 };
        var jsonString = JsonSerializer.Serialize(person, options);
        Console.WriteLine(jsonString);
    }
}
        
    

This example demonstrates advanced features of System.Text.Json, such as handling custom serialization.


6. Deserializing JSON to Dynamic Types

Sometimes, you may want to deserialize JSON data to dynamic types for flexibility. Here's how you can do it.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"John\",\"Age\":30}";
        var person = JsonConvert.DeserializeObject<dynamic>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
    }
}
        
    

This example shows deserializing a JSON string to a dynamic object.

        
            using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Person\":{\"Name\":\"Jane\",\"Age\":25}}";
        var jsonObject = JObject.Parse(jsonString);
        var person = jsonObject["Person"];
        Console.WriteLine($"Name: {person["Name"]}, Age: {person["Age"]}");
    }
}
        
    

This example demonstrates deserializing a more complex JSON structure to a dynamic object.


7. Deserializing JSON to Strongly Typed Objects

Deserializing JSON data to strongly-typed objects ensures type safety and better performance.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"John\",\"Age\":30}";
        var person = JsonSerializer.Deserialize<Person>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
    }
}
        
    

This example illustrates deserializing a JSON string to a strongly-typed object.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Address Address { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"Jane\",\"Age\":25,\"Address\":{\"Street\":\"123 Main St\",\"City\":\"Springfield\"}}";
        var person = JsonSerializer.Deserialize<Person>(jsonString);
        Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, Street: {person.Address.Street}, City: {person.Address.City}");
    }
}
        
    

This example demonstrates deserializing a complex JSON structure to a strongly-typed object.


8. Serializing Objects to JSON

Serializing objects to JSON is useful for sending data over the network or saving it to a file.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var person = new { Name = "John", Age = 30 };
        var jsonString = JsonConvert.SerializeObject(person);
        Console.WriteLine(jsonString);
    }
}
        
    

This example shows how to serialize a simple object to a JSON string.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Address Address { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person { Name = "Jane", Age = 25, Address = new Address { Street = "123 Main St", City = "Springfield" } };
        var jsonString = JsonConvert.SerializeObject(person);
        Console.WriteLine(jsonString);
    }
}
        
    

This example demonstrates serializing a complex object, including nested objects, to a JSON string.


9. Handling JSON Arrays

JSON arrays are common, especially when dealing with lists of objects. Here's how to handle JSON arrays in C#.

        
            using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "[{\"Name\":\"John\",\"Age\":30},{\"Name\":\"Jane\",\"Age\":25}]";
        var people = JsonConvert.DeserializeObject<List<dynamic>>(jsonString);
        foreach (var person in people)
        {
            Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
        }
    }
}
        
    

This example shows how to parse a JSON array into a list of dynamic objects.

        
            using System;
using System.Collections.Generic;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "[{\"Name\":\"John\",\"Age\":30},{\"Name\":\"Jane\",\"Age\":25}]";
        var people = JsonSerializer.Deserialize<List<Person>>(jsonString);
        foreach (var person in people)
        {
            Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
        }
    }
}
        
    

This example demonstrates parsing a JSON array into a list of strongly-typed objects.


10. Custom JSON Converters

Custom converters allow you to control the serialization and deserialization process for specific types.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class CustomDateTimeConverter : JsonConverter<DateTime>
{
    public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString("yyyy-MM-dd"));
    }

    public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        return DateTime.Parse(reader.Value.ToString());
    }
}

public class Person
{
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person { Name = "John", BirthDate = new DateTime(1990, 1, 1) };
        var settings = new JsonSerializerSettings();
        settings.Converters.Add(new CustomDateTimeConverter());
        var jsonString = JsonConvert.SerializeObject(person, settings);
        Console.WriteLine(jsonString);
    }
}
        
    

This example illustrates creating a custom converter for a specific type using Newtonsoft.Json.

        
            using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JsonHandlingExamples;

public class CustomDateTimeConverter : JsonConverter<DateTime>
{
    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
    }

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.Parse(reader.GetString());
    }
}

public class Person
{
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var options = new JsonSerializerOptions();
        options.Converters.Add(new CustomDateTimeConverter());

        var person = new Person { Name = "Jane", BirthDate = new DateTime(1995, 5, 5) };
        var jsonString = JsonSerializer.Serialize(person, options);
        Console.WriteLine(jsonString);
    }
}
        
    

This example demonstrates creating a custom converter using System.Text.Json.


11. Handling Date and Time in JSON

Date and time values often require special handling when working with JSON. Here's how to manage date and time serialization and deserialization.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"John\",\"BirthDate\":\"1990-01-01\"}";
        var person = JsonConvert.DeserializeObject<Person>(jsonString);
        Console.WriteLine($"Name: {person.Name}, BirthDate: {person.BirthDate:yyyy-MM-dd}");
    }
}
        
    

This example shows how to handle date and time using Newtonsoft.Json.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var jsonString = "{\"Name\":\"Jane\",\"BirthDate\":\"1995-05-05\"}";
        var person = JsonSerializer.Deserialize<Person>(jsonString);
        Console.WriteLine($"Name: {person.Name}, BirthDate: {person.BirthDate:yyyy-MM-dd}");
    }
}
        
    

This example demonstrates handling date and time using System.Text.Json.


12. Ignoring Properties During Serialization

Sometimes, you may need to ignore certain properties during serialization. Here's how you can do it.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    [JsonIgnore]
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person { Name = "John", Age = 30 };
        var jsonString = JsonConvert.SerializeObject(person);
        Console.WriteLine(jsonString);
    }
}
        
    

This example illustrates ignoring properties using attributes with Newtonsoft.Json.

        
            using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    [JsonIgnore]
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person { Name = "Jane", Age = 25 };
        var jsonString = JsonSerializer.Serialize(person);
        Console.WriteLine(jsonString);
    }
}
        
    

This example demonstrates ignoring properties using attributes with System.Text.Json.


13. JSON Serialization Settings

JSON serialization settings allow you to customize the behavior of the serializer.

        
            using System;
using Newtonsoft.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person { Name = "John", Age = 30 };
        var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
        var jsonString = JsonConvert.SerializeObject(person, settings);
        Console.WriteLine(jsonString);
    }
}
        
    

This example shows how to configure serialization settings with Newtonsoft.Json.

        
            using System;
using System.Text.Json;

namespace JsonHandlingExamples;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var options = new JsonSerializerOptions { WriteIndented = true };
        var person = new Person { Name = "Jane", Age = 25 };
        var jsonString = JsonSerializer.Serialize(person, options);
        Console.WriteLine(jsonString);
    }
}
        
    

This example demonstrates configuring serialization settings with System.Text.Json.


14. Validating JSON

Validating JSON ensures that the data conforms to the expected structure and types.

        
            using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Linq;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonSchema = JSchema.Parse("{ 'type': 'object', 'properties': { 'Name': { 'type': 'string' }, 'Age': { 'type': 'integer' } }, 'required': ['Name', 'Age'] }");
        var jsonString = "{\"Name\":\"John\",\"Age\":30}";
        var jsonObject = JObject.Parse(jsonString);
        bool isValid = jsonObject.IsValid(jsonSchema, out IList<string> errorMessages);

        Console.WriteLine($"IsValid: {isValid}");
        if (!isValid)
        {
            foreach (var error in errorMessages)
            {
                Console.WriteLine(error);
            }
        }
    }
}
        
    

This example illustrates validating JSON data using a schema with Newtonsoft.Json.

        
            using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Schema;
using System.Text.Json.Nodes;

namespace JsonHandlingExamples;

public class Program
{
    public static void Main(string[] args)
    {
        var jsonSchema = JsonNode.Parse("{ 'type': 'object', 'properties': { 'Name': { 'type': 'string' }, 'Age': { 'type': 'integer' } }, 'required': ['Name', 'Age'] }").AsObject();
        var jsonString = "{\"Name\":\"Jane\",\"Age\":25}";
        var jsonObject = JsonNode.Parse(jsonString).AsObject();
        bool isValid = jsonObject.Validate(jsonSchema, out IList<string> errorMessages);

        Console.WriteLine($"IsValid: {isValid}");
        if (!isValid)
        {
            foreach (var error in errorMessages)
            {
                Console.WriteLine(error);
            }
        }
    }
}
        
    

This example demonstrates validating JSON data with a schema using System.Text.Json.



15. Conclusion

Handling JSON in C# is a powerful capability that enables you to work with various data formats seamlessly. By using libraries like Newtonsoft.Json and System.Text.Json, you can efficiently parse, generate, and manipulate JSON data in your applications.