Working With JSON In C#






4.31/5 (6 votes)
Easy way to work with JSON file in C#/.NET
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 typeT
and returns the JSON code as astring
. -
string Serialize (Object obj, Type type, JsonSerializerOptions options)
Serializes
obj
oftype type
and returns JSON code asstring
. The last optional parameter,options
, allows you to specify additional serialization options. -
Task SerializeAsync (Object obj, Type type, JsonSerializerOptions options)
Serializes
obj
oftype type
and returns JSON code asstring
. 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 typeT
and returns the JSON code as astring
. -
object Deserialize (string json, Type type, JsonSerializerOptions options)
Deserializes the JSON
string
into anobject
oftype 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 anobject
of typeT
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
oftype type
. The last two parameters are optional:options
allows you to set additional deserialization options, andtoken
sets aCancellationToken
to cancel the task. Returns a deserializedobject
wrapped in aValueTask
. -
ValueTask <T> DeserializeAsync <T> (Stream utf8Json, JsonSerializerOptions options, CancellationToken token)
Deserializes the UTF-8 text that represents a JSON
object
into anobject
oftype T
. Returns a deserializedobject
wrapped in aValueTask
.
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:
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 object
s 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 serializedIgnoreNullValues
: Sets whether to serialize / deserialize in json objects and their properties tonull
WriteIndented
: Sets whether spaces are added to json (relatively speaking, for beauty). If set correctly, extra spacesAllowTrailingCommas
: An element whether to add a comma after the last one to json. If equal istrue
, 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.
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