26 September 2018
Categories: Software Development
Posted in: C#, .NET, JSON, JSON.NET, Serialization, Logging
Goals
Very often when coding, we have a need to output the current state of an object to show it or store it for later retrieval (logging is the most common example of this need). This article will teach you how to convert any object to a JSON string using one of the most common dependencies on Nuget.org: Json.NET
In order to output the state of an object, we can add custom code to format our output as needed. Here's an example when an object is serialized manually:
var output = new StringBuilder();
output.AppendFormat("ID: {0}\n", req.ID);
output.AppendFormat("Name: {0}\n", req.Name);
output.AppendFormat("Surname: {0}\n", req.Surname);
output.AppendFormat("Last Sign In: {0}\n", req.LastSignIn);
output.AppendFormat("Attributes:\n");
foreach (var s in req.Attributes)
{
output.AppendFormat(" {0}\n", s);
}
Logger.Info("Object status is: " + output.ToString());
The output will look as follows:
ID: 1
Name: Bill
Surname: Gates
Last Sign In: 9/26/2018 3:46:05 AM
Attributes:
Intelligent
Wealthy
Philanthropist
Visionary
There are several important drawbacks to logging data as the example above:
To output our objects, We can take advantage of JSON's formatting since it offers a readable representation of our object's state. Using C#, the simplest way to convert an object to JSON is via the use of Newtonsoft's Json.NET library. This library allow us to generate a complete string representation of our objects by using a single line of code.
Following the example of the manual serialization above, the whole output can be produced with Json.NET with little coding effort:
var output = Newtonsoft.Json.JsonConvert.SerializeObject(req);
Logger.Info("Object status is: " + output);
The output will look as follows:
{"ID":1,"Name":"Bill","Surname":"Gates","LastSignIn":"2018-09-26T03:46:05.3023879+00:00","Attributes":["Intelligent","Wealthy","Philanthropist","Visionary"]}
There are several relevant advantages to logging data as the example above: 1. One line of code will produce all the output 2. You don't need previous knowledge of the object type 3. Providing the logging mechanism through a dedicated class or function is trivial 4. Furure changes in the object's type definition are handled automatically, there's no need to maintain this code
In order to improve readability, Json.NET can also format the JSON output. Here's an example that will indent the JSON string:
var output = Newtonsoft.Json.JsonConvert.SerializeObject(req, Newtonsoft.Json.Formatting.Indented);
Logger.Info("Object status is: " + output);
The output will now look as follows:
{
"ID": 1,
"Name": "Bill",
"Surname": "Gates",
"LastSignIn": "2018-09-26T03:46:05.3023879+00:00",
"Attributes": [
"Intelligent",
"Wealthy",
"Philanthropist",
"Visionary"
]
}
Serializing an object with Json.NET will greatly simplify the coding needed to output an object's state. Json.NET offers all sorts of functionality, I encourage you to go through the documentation at https://www.newtonsoft.com/json
Here's a full C# example of the contents of this article.
Happy Coding! ;)
using System;
using System.Text;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var req = CreateRequest();
/* Manual output
* Advantages:
* Custom formatting
* Maximum readability
* Disadvantages:
* Coding required for each property
* Requires knowledge of object being outputted
* Changes in the object definition require additional coding
*/
var output = new StringBuilder();
// You need to manually output all properties
output.AppendFormat("ID: {0}\n", req.ID);
output.AppendFormat("Name: {0}\n", req.Name);
output.AppendFormat("Surname: {0}\n", req.Surname);
output.AppendFormat("Last Sign In: {0}\n", req.LastSignIn);
// Nested objects are particularly nasty to handle
output.AppendFormat("Attributes:\n");
foreach (var s in req.Attributes)
{
output.AppendFormat(" {0}\n", s);
}
Console.WriteLine(output.ToString());
/* Serialized output (Newtonsoft.Json)
* Advantages:
* One line of code, valid forever
* Doesn't require knowledge of object being outputted
* Changes in the object definition are handled automatically
* Disadvantages:
* JSON formatting, reduced readability for non-developers
*/
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(req));
// In order to improve readability, you may indent the JSON output
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(req, Newtonsoft.Json.Formatting.Indented));
}
public static Request CreateRequest()
{
return new Request
{
ID = 1,
Name = "Alex",
Surname = "Domenici",
LastSignIn = DateTime.Now,
Attributes = new List<string>
{
"Smart",
"Overweight",
"Funny",
"Old",
}
};
}
public class Request
{
public int ID {get;set;}
public string Name {get;set;}
public string Surname {get;set;}
public DateTime LastSignIn {get;set;}
public List<string> Attributes {get;set;}
}
}