Archives

Archives / 2014 / August
  • Json.NET 6.0 Release 4 - JSON Merge, Dependency Injection

    JSON Merge

    The most visible new feature in this release is the ability to quickly merge JSON using the Merge method added to JObject and JArray.

    JObject o1 = JObject.Parse(@"{
      'FirstName': 'John',
      'LastName': 'Smith',
      'Enabled': false,
      'Roles': [ 'User' ]
    }");
    JObject o2 = JObject.Parse(@"{
      'Enabled': true,
      'Roles': [ 'User', 'Admin' ]
    }");
     
    o1.Merge(o2, new JsonMergeSettings
    {
        // union array values together to avoid duplicates
        MergeArrayHandling = MergeArrayHandling.Union
    });
     
    string json = o1.ToString();
    // {
    //   "FirstName": "John",
    //   "LastName": "Smith",
    //   "Enabled": true,
    //   "Roles": [
    //     "User",
    //     "Admin"
    //   ]
    // }

    The logic for combining JSON objects together is fairly simple: name/values are copied across, skipping nulls if the existing property already has a value. Arrays are a bit more tricky in how they can be merged so there is a setting for you to specify whether arrays should be concatenated together, unioned, merged by position or completely replaced.

    Dependency Injection

    The low-level ConstructorInfo properties on JsonObjectContract, used when creating objects during deserialization, are now obsolete and have been replaced with functions. Also Json.NET no longer immediately throws an exception if it tries to deserialize an interface or abstract type. If you have specified a way for that type to be created, such as resolving it from a dependency inject framework, then Json.NET will happily continue deserializing using that instance.

    These changes combined make using Json.NET with dependency inject frameworks like Autofac, Ninject and Unity much simpler.

    public class AutofacContractResolver : DefaultContractResolver
    {
        private readonly IContainer _container;
     
        public AutofacContractResolver(IContainer container)
        {
            _container = container;
        }
     
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            JsonObjectContract contract = base.CreateObjectContract(objectType);
     
            // use Autofac to create types that have been registered with it
            if (_container.IsRegistered(objectType))
                contract.DefaultCreator = () => _container.Resolve(objectType);
     
            return contract;
        }
    }

    Performance Improvements

    There have been a lot of small performance improvements across Json.NET. All reflection is now cached or compiled into dynamic IL methods, large XML documents are converted to JSON much faster and JObject memory usage has been reduced.

    Changes

    Here is a complete list of what has changed since Json.NET 6.0 Release 3.

    • New feature - Added Merge to LINQ to JSON
    • New feature - Added JValue.CreateNull and JValue.CreateUndefined
    • New feature - Added Windows Phone 8.1 support to .NET 4.0 portable assembly
    • New feature - Added OverrideCreator to JsonObjectContract
    • New feature - Added support for overriding the creation of interfaces and abstract types
    • New feature - Added support for reading UUID BSON binary values as a Guid
    • New feature - Added MetadataPropertyHandling.Ignore
    • New feature - Improved performance of KeyValuePairConverter
    • New feature - Improved performance when serializing large XML documents
    • Change - Limited integer parsing size to JavaScript integer size
    • Change - Validation that numbers don't end with an invalid character
    • Fix - Fixed JToken.ReadFrom creating a string value for a comment
    • Fix - Fixed relying on Dictionary order when calling parameterized constructors
    • Fix - Fixed writing new lines to use TextWriter.WriteLine
    • Fix - Fixed deserializing non-generic IReadOnlyCollection<T> implementations
    • Fix - Fixed sending HTTP requests when resolving DTD urls in XmlNodeConverter
    • Fix - Fixed populating ignored properties with DefaultValueHandling.IgnoreAndPopulate
    • Fix - Fixed not throwing JsonReaderException when parsing some invalid numbers
    • Fix - Fixed JsonConvert.PopulateObject not setting JsonReader settings
    • Fix - Fixed deserializing JObjects starting with a comment
    • Fix - Fixed using DateParseHandling and FloatParseHandling with DataTable/DataSet
    • Fix - Fixed serializing static fields
    • Fix - Fixed selecting a property after an empty array with a JSON Path query
    • Fix - Fixed error handling when last value in array or object fails
    • Fix - Fixed directly serializing XmlElements
    • Fix - Fixed incorrect NuGet targets on .NET 4.5 portable assembly
    • Fix - Fixed using JTokenEqualityComparer with JProperties that have no value
    • Fix - Fixed MetadataPropertyHandling.ReadAhead bugs

    Links

    Json.NET GitHub Project

    Json.NET 6.0 Release 4 Download - Json.NET source code and assemblies