Wednesday, July 08, 2009

Json.NET and Its Usage (2)

In this blog, I'll continue to describe my wrapper class based on Json.Net. The main reason I want to write a wrapper class to hide Json.Net is to provide only APIs I am interested in. Json.Net provides a rich framework of classes, interfaces, types, and enums. I don't know all of them. In practice, there is no need to know all.

The second reason is to break direct dependency on Json.Net. My wrapper class provides all the APIs I need. There may be some cases in the future that a better library available than Json.Net or some potential problems preventing me from using Json.Net. Then what I need to do is to rewrite the wrapper class's internal implementation without change my application or libraries which are dependent on the wrapper class. Actually, I find this the best practice to use other library or components.

I created a common .Net library, DotNetCommonLibrary, with some common and generic classes, including my wrapper class for Json.Net. The first thing I need is to add a reference to Newtonsoft.Json to the library.

Next, I include the following namespace in the wrapper class:

# region Using
using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using Newtonsoft.Json;
using JsonFormatting = Newtonsoft.Json.Formatting;
using Newtonsoft.Json.Converters;
# endregion

The wrapper class is called as JsonXMLHelper. The class does not contain any private instance data, therefore, the class is a static class.

public static class JsonXMLHelper
{
...
}

The first method is a simple one: convert a Jsonstring to an instance.

public static T GetInstance<T>(
  string jsonString)
  where T : class
{
  T instance = JsonConvert.DeserializeObject(jsonString, typeof(T)) as T;
  return instance;
}


Vice-versa, there is the method to convert instance to Jsonstring:


public static string GetJsonString<T>(
  T instance) where T : class
{
  return GetJsonString<T>(instance, false);
}

public static string GetJsonString<T>(
  T instance,
  bool indented)
  where T : class
{
  return GetJsonString<T>(
    instance, indented, true, null);
}

public static string GetJsonString<T>(
  T instance,
  bool indented,
  bool quoteName,
  string dtFormat) where T : class
{
  JsonFormatting f = indented ?
    JsonFormatting.Indented :
    JsonFormatting.None;
  string jsonStr;
  // Date format available?
  if (!string.IsNullOrEmpty(dtFormat))
  {
    JsonSerializerSettings jss =
      new JsonSerializerSettings();
    IsoDateTimeConverter dtConvert =
      new IsoDateTimeConverter();
    dtConvert.DateTimeFormat = dtFormat;
    jss.Converters.Add(dtConvert);
    jsonStr = JsonConvert.SerializeObject(
      instance, f, jss);
  }
  else
  {
    jsonStr = JsonConvert.SerializeObject(
      instance, f);
  }

  if (!quoteName)
  {
    jsonStr = ConvertToFormattedJsonString(
      jsonStr, quoteName);
  }

  return jsonStr;
}

GetJsonstring() has several overloads, which provide options to specify if a Jsonstring is indented, if a quote " char is used for Jsonstring names, and what is the format for DateTime type. By default, a Jsonstring is not indented as one long string and Json names are quoted by ", and DateTime values are displayed in the format of Date(tick_numbers). I need to log some instances as Jsonstrings in a nice and readable format. Those overloads provide options I need.

I used this GetJsonstring() method a lot. It saves me a lots of time to override ToString() method to format instance in a nice string. The most frustrated thing is that when I update class property names, I often forget to update ToString(). With this API method, I don't need to worry about this.

I even don't need to override ToString() any more. I can directly call this method with an instance to get a nice Json string. It is the most handy way to print or log .Net or third party class instances. You can even print or log an instance of List<T> type, but be prepared for very long strings.

0 comments: