Json.NET 4.5 Release 2 – Serializable support and bug fixes

Serializable Support

Json.NET now detects types that have the SerializableAttribute and serializes all the fields on that type, both public and private, and ignores the properties. This is useful when you’re interested in round-tripping the data on a type and don’t care what the JSON looks like.

If you are serializing types that have the attribute and don’t want the new behaviour, it can either be overridden on a type using the JsonObjectAttribute or disabled globally by setting IgnoreSerializableAttribute on DefaultContractResolver to true.

Update: IgnoreSerializableAttribute is true by default in release 3. If you want it you can still achieve this effect by either setting IgnoreSerializableAttribute to false or adding [JsonObject(MemberSerialization.Fields)] to your class.

Bug fixes

Interesting bug fixes this release include correctly reading JSON from slow streams (e.g. a network stream that is only returning one character at a time), fixing invalid Unicode surrogate characters, and ignoring property order when comparing two JObjects (JavaScript objects aren’t ordered and so could come back serialized in a different order).

Changes

  • New feature - Added support for the SerializableAttribute and serializing a type's internal fields
  • New feature - Added MaxDepth to JsonReader/JsonSerializer/JsonSerializerSettings
  • New feature - Added support for ignoring properties with the NonSerializableAttribute
  • Fix - Fixed deserializing a null string throwing a NullReferenceException
  • Fix - Fixed JsonTextReader incorrectly reading from a slow stream
  • Fix - Fixed CultureInfo not being overridden on JsonSerializerProxy
  • Fix - Fixed full trust security check in .NET 2.0 & .NET 3.5
  • Fix - Fixed XmlNodeConverter not turning all attribute properties into attributes
  • Fix - Fixed comparing JObjects to ignore property order
  • Fix - Fixed reading invalid Unicode surrogate pairs

Links

Json.NET CodePlex Project

Json.NET 4.5 Release 2 Download – Json.NET source code, documentation and binaries

Json.NET Strong Naming and Assembly Version Numbers

In the Json.NET 4.5 release post I added a note about strong naming and assembly version numbers that is worth expanding on.

The problem is a combination of factors: Json.NET is strong named, has frequent releases, the assembly version number changes with each release and many different libraries reference Json.NET.

NuGet does its best to solve the issue of different assemblies referencing different versions by automatically inserting binding redirects for you, but having to rely on a tool to fix up problems is sub-optimal.

The solution that I’m evaluating to improve the situation is to only update the assembly version number on major releases (update: now evaluating never updating the assembly version). For example Json.NET 4.5 R1 has an assembly version number of 4.5.0.0, R2 will have an the version number 4.5.0.0, R3 = 4.5.0.0, and so on. While the assembly version number will be static the assembly file version number will continue to be updated each release so you can identify exactly which version you are using, e.g. 4.5.1.14720.

The .NET framework is doing something similar with .NET 4.5, replacing 4.0 assemblies with new files using the same version number.

Json.NET Metro Upgrade Kit

Metro Color Conversion

The Metro UI color scheme looks complex and hard to code for at first but Json.NET has everything under control with its advanced automatic Metro Color Enhancement Suite™.

Before:

Color[] colors = new []{ Color.Blue, Color.Red, Color.Yellow, Color.Green, Color.Black, Color.Brown };
 
string json = JsonConvert.SerializeObject(colors);
// ["Blue", "Red", "Yellow", "Green", "Black", "Brown"]

Hey, what’s the matter? Oh, right. My grotesque appearence!

Yuck! Color is so 2011.

Json.NET Metro Enhanced:

Color[] colors = new []{ Color.Blue, Color.Red, Color.Yellow, Color.Green, Color.Black, Color.Brown };
 
string json = JsonConvert.SerializeObject(colors);
//["Gray", "Gray", "Gray", "Gray", "Black", "Gray"]

Call me a killjoy, but I think that because this is not to my taste, no one else should be able to enjoy it.

Now my Metro application will fit right in!

Metro Text Rendering

The application now looks right but there is someone off about the content. Don’t fear, Json.NET’s Metro Integration automatically upgrades your existing content to be Windows 8 ready.

Before:

string json = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "ExpiryDate": "2012-04-01T00:00:00",
//  "Price": 3.99,
//  "Sizes": [ "Small", "Medium", "Large" ]
//}

Are these words? I can barely even read this!

Json.NET Metro Enhanced:

string json = JsonConvert.SerializeObject(product);
//{
//  ":::NAME:::": ":::APPLE:::",
//  ":::EXPIRYDATE:::": "2012-04-01T00:00:00",
//  ":::PRICE:::": 3.99,
//  ":::SIZES:::": [ ":::SMALL:::", ":::MEDIUM:::", ":::LARGE:::" ]
//}

Oh that’s much better.

In-place Upgrade Kit

Json.NET Metro Integration will be included in the next release but until then an upgrade kit has been put together. Begin building tomorrow’s next generation UIs today!

https://gist.github.com/2269465

string json = JsonConvert.SerializeObject(value, new JsonSerializerSettings
{
  ContractResolver = new MetroPropertyNameResolver(),
  Converters = { new MetroStringConverter(), new MetroColorConverter() },
  Formatting = Formatting.Indented
});

:::HAPPY CODING!!!!:::

Json.NET 4.5 Release 1 - ISO dates, Async, Metro build

This is the first major release of Json.NET 4.5. Read on for the details.

ISO Dates

Json.NET now writes dates as an ISO 8601 string by default instead of Microsoft’s format.

The reason for the change is the ISO format is becoming the standard for JSON libraries. All major browsers output an ISO date from the JSON.stringify function for example. Other benefits are the ISO 8601 standard is human readable unlike Unix ticks and the format is better at handling time zones.

This is a breaking change but there is option to make dates go back to what they were called DateFormatHandling. Setting DateFormatHandling on either the JsonSerializer or JsonSerializerSettings to MicrosoftDateFormat will keep your dates nice and Unix ticky.

Async Serialization

There are new helper methods on JsonConvert for serializing and deserializing JSON asynchronously.

private static async Task<ExpensiveViewModel> CreateExpensiveViewModel()
{
  // these happen simultaneously
  var people = JsonConvert.SerializeObjectAsync(GetPeople());
  var products = JsonConvert.SerializeObjectAsync(GetProducts());
 
  return new ExpensiveViewModel
  {
    People = await people,
    Products = await products
  };
}

Metro Build

Json.NET now supports Windows 8 Metro applications (i.e. WinRT). Since WinRT is still in beta, and because reflection has to be rewritten for this build (booo) there maybe bugs in more esoteric serialization scenarios.

Assembly Versioning

I’m going to experiment with only updating the assembly version at major version changes (i.e. 4.5.0.0) and letting the assembly file version keep the true version number, similar to what the ASP.NET team do with MVC assemblies. Breaking changes will only happen on major version changes.

Hopefully this should reduce the amount of assembly binding redirecting going on for everyone.

And other stuff

A sweet bug fix means that a performance test now runs 70,000% faster, the path of the current JSON location is now on JsonReader and exceptions for easier debugging and a potential security hole when serializing ISerializable types in partial trust has been closed.

Changes

Here is a complete list of what has changed since Json.NET 4.0 Release 8.

  • New feature - Windows 8 Metro build
  • New feature - JsonTextReader automatically reads ISO strings as dates
  • New feature - Added DateFormatHandling to control whether dates are written in the MS format or ISO format, with ISO as the default
  • New feature - Added DateTimeZoneHandling to control reading and writing DateTime time zone details
  • New feature - Added async serialize/deserialize methods to JsonConvert
  • New feature - Added Path to JsonReader/JsonWriter/ErrorContext and exceptions with the JSON path of the current position
  • New feature - Added collection type to JsonArrayContract
  • New feature - Added dictionary key type and dictionary value type to JsonDictionaryContract
  • New feature - Added reader/writer specific Formatting, DateFormatHandling and DateTimeZoneHandling to JsonSerializerSettings
  • New feature - Added ReadAsDate and ReadAsString to JsonReader
  • New feature - Added IgnoreSerializableInterface to DefaultContractResolver
  • Change - Dates are now serialized as the ISO format by default
  • Change - The ReadAsXXX methods on JsonReader now return null at the end of an array instead of throwing an error
  • Change - JsonReaders now to set TokenType to JsonToken.None after finishing content
  • Change - Deserializing will fallback to use a private default constructor
  • Change - The error message when deserializing a JSON object/array onto the wrong kind of type is more descriptive
  • Change - Serializing ISerializable types under partial trust now errors to fix potential security issue
  • Fix - Fixed reading scientific notation numbers with no decimal point
  • Fix - Fixed LinqBridge collision error in .NET 2.0 by moving types to a different namespace
  • Fix - Fixed error when deserializing nullable types with no content
  • Fix - Fixed JObject.Keys null reference error when the object has no items
  • Fix - Fixed error handling when failing to parse array content
  • Fix - Fixed error handling when there are missing required properties
  • Fix - Fixed performance issue when building deeply nested JSON to LINQ to JSON objects

Links

Json.NET CodePlex Project

Json.NET 4.5 Release 1 Download – Json.NET source code, documentation and binaries