Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Working With JSON In C#

0.00/5 (No votes)
14 Mar 2021 1  
Easy way to work with JSON file in C#/.NET
In this article, I show you the basic operations with JSON. This is one of the key topics in learning C#.

Introduction

Today, JSON is one of the main formats for representing complex structures and data exchange. Therefore, all major programming languages have built-in support for working with it. C# is no exception. In this article, I would like to tell you about an easy way to work with JSON file in C#/.NET. I would like to show you simple examples with this format.

Background

There are at least two main ways to work .NET objects to JSON:

  • Using the DataContractJsonSerializer class
  • Using the JsonSerializer class

Les’s look at the JsonSerializer class. This class allows you to serialize an object to JSON and, conversely, deserialize JSON code to a C # object.

To save an object to JSON, the JsonSerializer class defines a static method called Serialize(), which has a number of overloads. Some of them are:

  • string Serialize <T> (T obj, JsonSerializerOptions options)

    The typed version serializes the obj object of type T and returns the JSON code as a string.

  • string Serialize (Object obj, Type type, JsonSerializerOptions options)

    Serializes obj of type type and returns JSON code as string. The last optional parameter, options, allows you to specify additional serialization options.

  • Task SerializeAsync (Object obj, Type type, JsonSerializerOptions options)

    Serializes obj of type type and returns JSON code as string. The last optional parameter, options, allows you to specify additional serialization options.

  • Task SerializeAsync <T> (T obj, JsonSerializerOptions options)

    The typed version serializes the obj object of type T and returns the JSON code as a string.

  • object Deserialize (string json, Type type, JsonSerializerOptions options)

    Deserializes the JSON string into an object of type type and returns the deserialized object. The last optional parameter, options, allows you to specify additional deserialization options.

  • T Deserialize <T> (string json, JsonSerializerOptions options)

    Deserializes a json string into an object of type T and returns it.

  • ValueTask <object> DeserializeAsync 
    (Stream utf8Json, Type type, JsonSerializerOptions options, CancellationToken token)

    Deserializes UTF-8 text that represents a JSON object into an object of type type. The last two parameters are optional: options allows you to set additional deserialization options, and token sets a CancellationToken to cancel the task. Returns a deserialized object wrapped in a ValueTask.

  • ValueTask <T> DeserializeAsync <T> 
    (Stream utf8Json, JsonSerializerOptions options, CancellationToken token)

    Deserializes the UTF-8 text that represents a JSON object into an object of type T. Returns a deserialized object wrapped in a ValueTask.

Getting the New JSON Library

  • If you’re targeting .NET Core. Install the latest version of the NET Core. This gives you the new JSON library and the ASP.NET Core integration.
  • If you’re targeting .NET Standard or .NET Framework. Install the System.Text.Json NuGet package (make sure to include previews and install version 4.6.0-preview6.19303.8 or higher). In order to get the integration with ASP.NET Core, you must target .NET Core 3.0.

Points of Interest

Let's consider the use of the class using a simple example. Serialize and deserialize the simplest object:

class Cellphone
    {
        public string Name { get; set; }
        public float Price { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Cellphone cellphone1 = new Cellphone { Name = "Iphone 12", Price = 750.00f };
            string json = JsonSerializer.Serialize<Cellphone>(cellphone1);
            Console.WriteLine(json);
            Cellphone restoredcellphone = JsonSerializer.Deserialize<Cellphone>(json);
            Console.WriteLine(restoredcellphone.Name +" "+  
                              Convert.ToString( restoredcellphone.Price));
            Console.ReadLine();
        }

In this case, we have the object with type Cellphone and then this object was serialized by method JsonSerializer.Serialize(). Then we made deserialize from this JSON in the object with type Cellphone using method JsonSerializer.Deserialize(). In Image 1, we have the result:

Image 1

Image 1 – The result by JsonSerializer.Serialize() and JsonSerializer.Deserialize() methods.

Moreover, for serializing/ deserializing, we can use a structure.

Only public properties of an object (with the public modifier) are subject to serialization.

The object being deserialized must have a parameterless constructor. For example, in the example above, this is the default constructor, but you can also explicitly define a similar constructor in a class.

Writing and Reading JSON File

We can create a JSON file because SerializeAsyc/DeserializeAsync can accept stream for saving and writing data. Let’s consider an instance.

class Cellphone
    {
        public string Name { get; set; }
        public float Price { get; set; }
    }
    class Program
    {
        static async Task Main(string[] args)
        {
            using (FileStream fs = new FileStream("cellphone.json", FileMode.OpenOrCreate))
            {
                Cellphone cellphone1 = new Cellphone { Name = "Iphone 12", Price = 750.00f };
                await JsonSerializer.SerializeAsync<Cellphone>(fs, cellphone1);
                Console.WriteLine("We are done.File has benn saved");
            }
            using (FileStream fs = new FileStream("cellphone.json", FileMode.OpenOrCreate))
            {
                Cellphone restoredcellphone1 = 
                          await JsonSerializer.DeserializeAsync<Cellphone>(fs);
                Console.WriteLine($"Name: {restoredcellphone1.Name}  
                                  Price: {restoredcellphone1.Price}");
            }

            Console.ReadLine();
        }
    }

Here, we used using because FileStream is an uncontrolled resource and Data has been written and read.

Serialization Settings by JsonSerializerOptions

By default, the JsonSerializer serializes objects to minified code. With an add-on package like JsonSerializerOptions, you can customize the serialization / deserialization engine using the JsonSerializerOptions properties. Some of its properties are as given below:

  • IgnoreReadOnlyProperties: Similarly sets whether read-only properties are serialized
  • IgnoreNullValues: Sets whether to serialize / deserialize in json objects and their properties to null
  • WriteIndented: Sets whether spaces are added to json (relatively speaking, for beauty). If set correctly, extra spaces
  • AllowTrailingCommas: An element whether to add a comma after the last one to json. If equal is true, a comma is added

Customizing Serialization using Attributes

By default, all public properties are serialized. Also, in the output json object, all property names match the property names of the C # object. However, using the JsonIgnore and JsonPropertyName attributes.

The JsonIgnore attribute allows you to exclude a specific property from serialization. JsonPropertyName allows you to override the original property name. Let's consider an example:

class Cellphone
{
    [JsonPropertyName("NameOfCellPhone")]
    public string Name { get; set; }
    [JsonIgnore]
    public float Price { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        Cellphone cellphone1 = new Cellphone() { Name = "Iphone 12", Price = 750.00f };
        string json = JsonSerializer.Serialize<Cellphone>(cellphone1);
        Console.WriteLine(json);
        Cellphone restoredPerson = JsonSerializer.Deserialize<Cellphone>(json);
        Console.WriteLine($"CellPhone: {restoredPerson.Name}
                          Price: {restoredPerson.Price}");

        Console.ReadLine();
    }

The result is on image 2.

Image 2

Image 2 - The result of JsonIgnore

In this case, the Price property was ignored and the " NameOfCellPhone " alias will be used for the CellPhone property. Note that since the Priceproperty has not been serialized, it uses its default value when deserialized.

In conclusion, JSON is one of the main formats for representing complex structures and data exchange. In addition, all major programming languages have built-in support for working with it and C # is no exception.

History

  • 17th February, 2021: Initial version
 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here