Serializing an object to Json using C#

Goals

  • Convert an object to a JSON string
  • Make the JSON string as readable as possible
  • Minimize the coding effort

Serializing an object to json using C#

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

Manual Serialization

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:

  1. Coding is required for each property of the object, code becomes particularly nasty for lists and nested objects
  2. We need to have detailed knowledge of the type of the object
  3. Changes in the object type definition will not automatically reflect in out output, unless we come back to the code and change it
  4. We quickly lose readability because we're littering out functions with code that doesn't have any functional use
  5. Generalizing the logging mechanism into a dedicated class or function is not possible

JSON Serialization

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"
  ]
}

Conclusions

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;}
    }
}
comments powered by Disqus