Json.NET 5.0 Release 5 – DefaultSettings and Extension Data

DefaultSettings

If you have used Json.NET then you will be familiar with JsonSerializerSettings. This class has been an extremely successful at providing an simple way for developers to customize Json.NET.

With Json.NET’s increasing popularity and its use by more third party frameworks, a problem I have noticed is a developer has to customize serializer settings in multiple places. If you want your HtmlHelper.ToJson extension method, Web API services and SignalR to serialize JSON the same way across an application then you have to manually share a JsonSerializerSettings instance between them and figure out how each different framework allows you to customize Json.NET.

The solution I have come up with is to add global default settings. Set once with JsonConvert.DefaultSettings in an application, the default settings will automatically be used by all calls to JsonConvert.SerializeObject/DeserializeObject, and JToken.ToObject/FromObject. Any user supplied settings to these calls will override the default settings.

// settings will automatically be used by JsonConvert.SerializeObject/DeserializeObject
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
  {
    Formatting = Formatting.Indented,
    ContractResolver = new CamelCasePropertyNamesContractResolver()
  };
 
Employee e = new Employee
  {
    FirstName = "Eric",
    LastName = "Example",
    BirthDate = new DateTime(1980, 4, 20, 0, 0, 0, DateTimeKind.Utc),
    Department = "IT",
    JobTitle = "Web Dude"
  };
 
string json = JsonConvert.SerializeObject(e);
// {
//   "firstName": "Eric",
//   "lastName": "Example",
//   "birthDate": "1980-04-20T00:00:00Z",
//   "department": "IT",
//   "jobTitle": "Web Dude"
// }

Because there are cases where JSON should not be customized, e.g. a Facebook or Twitter library, by default JsonSerializer won’t use DefaultSettings, providing an opt-out for those frameworks or for places in your application that shouldn’t use default settings. To create a JsonSerializer that does use them there is a new JsonSerializer.CreateDefault() method.

In the short term there will be some third party libraries that don’t use default settings that should, and some third party libraries that do use default settings that shouldn’t. If you encounter a situation where DefaultSettings doesn’t work for you then continue to customize Json.NET settings like you do today.

In the long term DefaultSettings will hopefully provide a simple, standard way to developers to customize JSON in .NET applications.

Extension Data

The second new feature in Json.NET 5.0 Release 5 is copied inspired by WCF’s IExtensibleDataObject.

Extension data is a JSON object’s values that aren’t matched to a .NET property during deserialization. By placing the JsonExtensionDataAttribute on a dictionary all unused values are automatically added to that dictionary and are accessible by you.

public class DirectoryAccount
{
  // normal deserialization
  public string DisplayName { get; set; }
 
  // these properties are set in OnDeserialized
  public string UserName { get; set; }
  public string Domain { get; set; }
 
  [JsonExtensionData]
  private IDictionary<string, JToken> _additionalData;
 
  [OnDeserialized]
  private void OnDeserialized(StreamingContext context)
  {
    // SAMAccountName is not deserialized to any property
    // and so it is added to the extension data dictionary
    string samAccountName = (string)_additionalData["SAMAccountName"];
 
    Domain = samAccountName.Split('\\')[0];
    UserName = samAccountName.Split('\\')[1];
  }
}

Changes

Here is a complete list of what has changed since Json.NET 5.0 Release 4.

  • New feature – Added global default serialization settings with JsonConvert.DefaultSettings
  • New feature – Added extension data support with JsonExtensionDataAttribute
  • New feature – Added NullValueHandling and DefaultValueHandling support to serializing dynamic types
  • Change – Changed some explicit interface methods on JArray to public to support use with ImpromtuInterface
  • Fix – Fixed deserializing non-ISO formatted date dictionary keys
  • Fix – Fixed values not being set when deserializing with DefaultValueHandling.IgnoreAndPopulate
  • Fix – Fixed deserializing with type named handling and assemblies loaded with Assembly.LoadFrom
  • Fix - Fixed deserializing Regexes when using StringEnumConverter
  • Fix – Fixed serializing and deserializing typed DataSets

Links

Json.NET CodePlex Project

Json.NET 5.0 Release 5 Download – Json.NET source code and assemblies