Archives

Archives / 2014 / April
  • Json.NET 6.0 Release 3 - Serialize All The F#

    MOAR F#

    Json.NET 6.0 added support for F# discriminated unions - this release adds support for F# collections. F# lists, sequences, sets and maps now serialize and deserialize automatically.

    type Movie = {
        Name : string
        Year: int
    }
     
    [<EntryPoint>]
    let main argv = 
     
        let movies = [
            { Name = "Bad Boys"; Year = 1995 };
            { Name = "Bad Boys 2"; Year = 2003 }
        ]
     
        let json = JsonConvert.SerializeObject(movies)
     
        let deserializedMovies = JsonConvert.DeserializeObject<Movie list>(json)
     
        deserializedMovies |> List.iter (fun x -> printfn "Name: %s, Year: %d" x.Name x.Year)
        // Name: Bad Boys, Year: 1995
        // Name: Bad Boys 2, Year: 2003
     
        Console.ReadKey() |> ignore
        0

    To all future creators of immutable .NET collections: If your collection of T has a constructor that takes IEnumerable<T> then Json.NET will automatically work when deserializing to your collection, otherwise you're all out of luck.

    Metadata Property Handling

    Some Json.NET serializer features like preserving types or references require Json.NET to read and write metadata properties, e.g. $type, $id and $ref. Because of the way Json.NET deserialization works these metadata properties have had to be ordered first in a JSON object. This can cause problems because JSON object properties can't be ordered in JavaScript and some other JSON frameworks.

    This release adds a new setting to allow metadata properties to be located anywhere in an object: MetadataPropertyHandling.ReadAhead

    string json = @"{
        'Name': 'James',
        'Password': 'Password1',
        '$type': 'MyNamespace.User, MyAssembly'
    }";
     
    object o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All,
        // $type no longer needs to be first
        MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
    });
     
    User u = (User)o;
     
    Console.WriteLine(u.Name);
    // James

    Internally this setting will instruct the serializer to load the entire JSON object into memory. Metadata properties will then be read out of the object, and then deserialization will continue as normal. There is a slight cost in memory usage and speed but if you require a feature that uses metadata properties and can't guarantee JSON object property order then you will find this useful.

    And The Rest

    DateFormatString is now used as a fallback when parsing dates during deserialization, lots of bug fixes, and a couple of small but significate performance improvements.

    Changes

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

    • New feature - Added MetadataPropertyHandling
    • New feature - Added support for reading MS format JSON dates to ReadAsDateTime
    • New feature - Added support for serializing F# lists, sets and maps
    • New feature - Added support for XML document type
    • Change - Blank XML elements will be written as an empty string instead of null
    • Change - JValue with a null value will be written as null instead of empty string
    • Change - DateFormatString is now used when reading JSON
    • Fix - Fixed deserializing null values with extension data
    • Fix - Fixed converting certain XML namespaces to JSON
    • Fix - Fixed error with whitespace only JSONPath
    • Fix - Fixed property query path that starts with $
    • Fix - Fixed array query path with open brace after $
    • Fix - Fixed parsing certain JSON with comments into a JObject
    • Fix - Fixed bug where matching JSONPath incorrectly raises an error
    • Fix - Fixed non-public base class properties being used instead of child class properties
    • Fix - Fixed hiding generic properties sometimes not being detected
    • Fix - Fixed potential race condition serializing F# objects
    • Fix - Fixed schema divisible sometimes incorrectly validating to false
    • Fix - Fixed not calling virtual ShouldSerialize methods
    • Fix - Fixed invalid cast with DateParseHandling.DateTimeOffset and IsoDateTimeConverter
    • Fix - Fixed StringEnumConverter thread safety
    • Fix - Fixed using FloatParseHandling.Decimal with XmlNodeConverter
    • Fix - Fixed using DateParseHandling.DateTimeOffset with XmlNodeConverter
    • Fix - Fixed type name handling when a property already has a base type assigned

    Links

    Json.NET GitHub Project

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