James Newton-King: Recent Episodes

None

View Details

gRPC is a modern way to communicate between apps. gRPC uses HTTP/2, streaming, Protobuf and message contracts to create high-performance, realtime services. Support for gRPC on ASP.NET Core was added in .NET Core 3.0.

The catch with gRPC is not every platform can use it. Browsers don't fully support HTTP/2, making REST and JSON still the primary way to get data into your browser apps. Even with the benefits that gRPC brings, REST and JSON still have an important place in modern apps. Building gRPC and REST services adds unwanted overhead to app development.

Wouldn't it be great if we could build services once in ASP.NET Core and get gRPC and REST? Now you can! Introducing gRPC HTTP API for ASP.NET Core.

gRPC or REST? Why not both

gRPC HTTP API is an experimental extension for ASP.NET Core that creates RESTful HTTP APIs for gRPC services. Once configured, gRPC HTTP API allows you to call gRPC methods with familiar HTTP concepts:

  • HTTP verbs
  • URL parameter binding
  • JSON requests/responses

RESTful APIs for your gRPC services. No duplication!

Demo

Visit https://grpchttpapi.azurewebsites.net/ to see gRPC HTTP API in action.

Source code of the demo is available here.

Getting started

  1. The first step is to create a gRPC service (if you don't already have one). Create a gRPC client and service is a great tutorial for getting started with gRPC on .NET Core.
  2. Next, add a package reference to Microsoft.AspNetCore.Grpc.HttpApi to the server. Register it in Startup.cs with services.AddGrpcHttpApi().
  3. The last step is annotating your gRPC .proto file with HTTP bindings and routes. The annotations define how gRPC services map to the JSON request and response. You will need to add import "google/api/annotations.proto"; to the gRPC proto file and have a copy of annotations.proto and http.proto in your project.

syntax = "proto3";

import "google/api/annotations.proto";

package greet;

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/v1/greeter/{name}"
};
}
rpc SayHelloFrom (HelloRequestFrom) returns (HelloReply) {
option (google.api.http) = {
post: "/v1/greeter"
body: "*"
};
}
}

message HelloRequest {
string name = 1;
}

message HelloRequestFrom {
string name = 1;
string from = 2;
}

message HelloReply {
string message = 1;
}

In the sample above, the SayHello gRPC method can now be invoked as gRPC and as a RESTful API:

  • Request: HTTP/1.1 GET /v1/greeter/world
  • Response: { "message": "Hello world" }

And browser apps call it like any other RESTful API:

fetch('https://localhost:5001/v1/greeter/world')
.then((response) => response.json())
.then((result) => {
console.log(result.message);
// Hello world
});

This is a simple example. See HttpRule for more customization options.

FAQ

Q: Are RESTful APIs for gRPC a brand new concept?

A: No. grpc-gateway provides RESTful JSON services for gRPC using the same .proto annotations. grpc-gateway is in heavy use today. For example, GCP uses it to offer gRPC and REST endpoints for GCP services. A key difference between the two technologies is grpc-gateway requires a reverse proxy, while gRPC HTTP API is hosted directly by ASP.NET alongside the gRPC service.

Q: Does this replace ASP.NET Core MVC?

A: No. gRPC HTTP API only supports JSON, and it is very opinionated. Only customization options offered by HttpRule are supported. A good scenario to use gRPC HTTP API is building new services using gRPC and JSON.

Q: How is this different than gRPC-Web?

A: gRPC-Web lets you call gRPC services from the browser with the gRPC-Web client and Protobuf. gRPC HTTP API allows you to call your services as if they were RESTful APIs with JSON. It doesn't replace gRPC-Web.

Q: When will this be released?

A: A pre-release package is on NuGet right now! gRPC HTTP API is an experiment and the decision to invest more time on it depends on user feedback.

Try it today!

gRPC HTTP API is a framework idea that I have been playing around with. It is very experimental, but I think it has the opportunity for .NET developers to offer gRPC and REST services much faster than they can today.

  • GrpcHttpApi @ aspnet/AspLabs repository on GitHub - Source code and instructions
  • Microsoft.AspNetCore.Grpc.HttpApi package on NuGet.org - Pre-release package

You can use the pre-release package on NuGet now. Whether more time is invested in making it a supported product depends on user feedback. Give feedback on GitHub or contact me @JamesNK on Twitter. I'm looking forward to seeing how this framework is used.

View Details

.NET Foundation

Json.NET has joined the .NET Foundation! The .NET Foundation is an independent organization dedicated to fostering the .NET open source community. The .NET Foundation provides technical and legal guidance .NET open source projects. Joining the .NET Foundation ensures that Json.NET stays open and supported into the future.

Read more on the .NET Foundation blog.

NuGet package and Authenticode signing

Json.NET 12 is the first release to sign the *.nupkg using NuGet package signing and sign the assembly files using Authenticode. Although it isn't a common request, some users of Json.NET have asked for signed binaries because of company policy. This feature is made possible by the .NET Foundation, who offer code signing certificates and a signing service to member projects.

Better debugging with SourceLink

SourceLink is an neat technology that links a library to its source code. Originally created in the community by @ctaggart, SourceLink has been adopted by Microsoft and is supported in Visual Studio. This release adds SourceLink support to Json.NET, making it possible to step into the Json.NET source code as you debug your application.

And lots more

JSON Path supports JavaScript's strict equality operators (=== & !==), StringEnumConverter can use a NamingStrategy and is faster, JavaScriptDateTimeConverter supports JavaScript date constructors with multiple arguments, there is a new option on JsonMergeSettings for case insensitive merging of property names, serializing Span properties no longer errors, and dozens of other new features and bug fixes.

Changes

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

  • New feature - Added NuGet package signing
  • New feature - Added Authenticode assembly signing
  • New feature - Added SourceLink support
  • New feature - Added constructors to StringEnumConverter for setting AllowIntegerValue
  • New feature - Added JsonNameTable and JsonTextReader.PropertyNameTable
  • New feature - Added line information to JsonSerializationException
  • New feature - Added JObject.Property overload with a StringComparison
  • New feature - Added JsonMergeSettings.PropertyNameComparison
  • New feature - Added support for multiple Date constructors with JavaScriptDateTimeConverter
  • New feature - Added support for strict equals and strict not equals in JSON Path queries
  • New feature - Added EncodeSpecialCharacters setting to XmlNodeConverter
  • New feature - Added trace message for serializing to non-writable properties
  • New feature - Added support for NamingStrategy to StringEnumConverter
  • New feature - Added JsonLoadSettings.DuplicatePropertyNameHandling setting
  • Change - JTokenReader now uses JsonReader.DateTimeZoneHandling setting for date values
  • Change - Excluded TargetSite when serializing Exceptions without SerializableAttribute
  • Change - Changed StringEnumConverter.ctor(bool camelCaseText) to obsolete
  • Change - Changed StringEnumConverter.CamelCaseText to obsolete
  • Fix - Fixed incorrect overflow when reading decimal values from JSON
  • Fix - Fixed error message when trying to deserialize an abstract serializable type
  • Fix - Fixed parsing decimals from a string with an exponent
  • Fix - Fixed losing DateTime.Kind when deserializing ISO date strings
  • Fix - Fixed calling constructors with ref and in parameters
  • Fix - Fixed rare race condition in name table when serializing
  • Fix - Fixed unhelpful exception message when unable to convert JSON value to DateTime
  • Fix - Fixed error when deserializing empty array in DataTable
  • Fix - Fixed deserializing empty string to empty byte array
  • Fix - Fixed blank extension data values with required properties and deserializing with constructor
  • Fix - Fixed ignored values being set in extension data when deserializing
  • Fix - Fixed comparing equal integer and floating point values in JSON Path
  • Fix - Fixed BsonReader when reading multiple content
  • Fix - Fixed setting extension data with existing key
  • Fix - Fixed including array attribute in XML with namespaces when converting JSON to XML
  • Fix - Fixed error when serializing ref struct properties by excluding them from serialization

Links

Json.NET GitHub Project

Json.NET 12.0 Release 1 Download - Json.NET source code and assemblies

View Details

.NET Standard 2.0

The big new feature in Json.NET 11 Release 1 is targeted support for .NET Standard 2.0.

There are two main benefits of a library like Json.NET targeting .NET Standard 2.0. The first is more APIs: Json.NET with .NET Standard 2.0 almost matches Json.NET on the traditional Windows .NET Framework in features.

For example, fans of serializing DataSets to and from JSON rejoice, .NET Core now supports your pro-DataSet lifestyle:

DataTable dt = new DataTable();
dt.Columns.Add("PackageId", typeof(string));
dt.Columns.Add("Version", typeof(string));
dt.Columns.Add("ReleaseDate", typeof(DateTime));

dt.Rows.Add("Newtonsoft.Json", "11.0.1", new DateTime(2018, 2, 17));
dt.Rows.Add("NUnit", "3.9.0", new DateTime(2017, 11, 10));

string json = JsonConvert.SerializeObject(dt, Formatting.Indented);

Console.WriteLine(json);
// [
// {
// "PackageId": "Newtonsoft.Json",
// "Version": "11.0.1",
// "ReleaseDate": "2018-02-17T00:00:00"
// },
// {
// "PackageId": "Newtonsoft.Json",
// "Version": "10.0.3",
// "ReleaseDate": "2017-06-18T00:00:00"
// }
// ]

The other benefit of .NET Standard 2.0 is developers are no longer spammed with NuGet dependencies. UWP app authors for example saw NuGet pull in over 100 packages when referencing Json.NET. UWP supporting .NET Standard 2.0 and consuming a netstandard2.0 package eliminates that problem.

JsonConverter Stuff

Json.NET 11 adds a generic JsonConverter. If you only care about serializing one specific type then JsonConverter eliminates boiler plate code from your converter and keeps everything strongly typed.

Also new is a UnixDateTimeConverter. There is no standard for serializing dates in JSON and so UnixDateTimeConverter is a useful converter for anyone who want to store time as an integer Unix epoch in their JSON.

JSON Path Stuff

Json.NET 11 adds support for the regular expression operator in JSON Path queries. JSON Path has no formal specification (other than a blog post) but one common addition to it is support for querying with regular expressions.

JArray packages = JArray.Parse(@"[
{
""PackageId"": ""Newtonsoft.Json"",
""Version"": ""11.0.1"",
""ReleaseDate"": ""2018-02-17T00:00:00""
},
{
""PackageId"": ""NUnit"",
""Version"": ""3.9.0"",
""ReleaseDate"": ""2017-11-10T00:00:00""
}
]");

List newtonsoftPackages = packages.SelectTokens(@"$.[?(@.PackageId =~ /^Newtonsoft.(.*)$/)]").ToList();

Console.WriteLine(newtonsoftPackages.Count);
// 1

JSON Path has also seen many smaller bug fixes this release to improve its performance and support of escaped characters.

And lots more

Serializing and deserializing enumerations by name is faster and more accurate, JsonReader.SupportMultipleContent supports reading multiple comma delimited fragments of JSON together, JObject exposes ContainsKey, error messages have improved in many exceptional situations, and dozens of other new features and bug fixes.

Changes

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

  • New feature - Added netstandard2.0 build
  • New feature - Added generic JsonConverter
  • New feature - Added UnixDateConverter for converting Unix timestaps
  • New feature - Added support for regex operator in JSON Paths
  • New feature - Added JsonObjectAttribute.ItemNullValueHandling
  • New feature - Added JsonObjectContract.ItemNullValueHandling
  • New feature - Improved performance when resolving serialization contracts by using ConcurrentDictionary
  • New feature - Improved performance of JToken.Path with a faster reverse
  • New feature - Improved performance of parsing Int32 JSON integer values
  • New feature - Improved performance of parsing and writing enum names
  • New feature - Added IgnoreIsSpecifiedMembers to DefaultContractResolver
  • New feature - Added IgnoreShouldSerializeMembers to DefaultContractResolver
  • New feature - Added support for reading multiple comma delimited values with JsonReader.SupportMultipleContent
  • New feature - Improved error message when an object is reused with PreserveReferencesHandling
  • New feature - Added IConvertible support to netstandard1.3
  • New feature - Added INotifyPropertyChanging support to netstandard1.3
  • New feature - Optimized internal buffering when writing very large strings
  • New feature - JObject.ContainsKey is now public
  • New feature - Improved the error message when serialized ByRef properties
  • New feature - Improved the error message when serializing FileInfo/DictionaryInfo without ISerializable
  • New feature - Improved the error message when failing conversion in JsonReader.ReadAsInt32 and JsonReader.ReadAsDecimal
  • New feature - Improved the error message when deserializing badly formatted regex strings
  • Change - Types that implement ISerializable but don't have [SerializableAttribute] are not serialized using ISerializable
  • Change - Changed JsonProperty.MemberConverter to obsolete
  • Change - Changed camel casing logic for all caps words to not leave last character capitalized
  • Change - Changed enum serialization in dictionary keys to use EnumMemberAttribute
  • Fix - Fixed converting default datetime in JSON to XML on netstandard1.3
  • Fix - Fixed deserializing ObservableCollection in .NET Core 2.0
  • Fix - Fixed incorrectly allowing static IsSpecified properties
  • Fix - Fixed not preserving trailing zeros when deserializing decimals
  • Fix - Fixed JValue.CompareTo with number and string values
  • Fix - Fixed not erroring when reading undefined for nullable long
  • Fix - Fixed serializing immutable collections when .NET 4.0 or previous Newtonsoft.Json assembly is GACed
  • Fix - Fixed writing null values by XmlNodeConverter and RegexConverter
  • Fix - Fixed deserializing with a TraceWriter when the reader is not at the start
  • Fix - Fixed TraceJsonWriter.WriteValue(object) writing value twice
  • Fix - Fixed deserializing with constructor and readonly collection property
  • Fix - Fixed error when writing unknown null value as JSON
  • Fix - Fixed merging null string values
  • Fix - Fixed missing CancellationToken usages in JsonTextWriter.WriteAsync
  • Fix - Fixed error with JsonSerializer.Populate and comments in JSON array
  • Fix - Fixed error handling when deserializing certain dictionary and lists
  • Fix - Fixed serializing collection that is nullable
  • Fix - Fixed JsonTextReader sync read in async method
  • Fix - Fixed JsonConverter not called when target type is list and token is a string
  • Fix - Fixed serializing a property that is defined in multiple interfaces
  • Fix - Fixed error when deserializing null value into ConcurrentDictionary
  • Fix - Fixed escaping special characters in generated JSON Paths
  • Fix - Fixed reading escaped special characters in JSON Paths
  • Fix - Fixed using extension data with dictionary that explicitly implements Add method
  • Fix - Fixed parsing enum name to exact casing value before falling back to case-insensitive value
  • Fix - Fixed DataContractAttribute not forcing object serialization of classes
  • Fix - Fixed bug when deserializing into existing non-IList collection
  • Fix - Fixed bug when deserializing into existing non-IDictionary collection
  • Fix - Fixed JsonReader.ReadAsInt32 with BigInteger values

Links

Json.NET GitHub Project

Json.NET 11.0 Release 1 Download - Json.NET source code and assemblies

View Details

Async support

The headline feature in Json.NET 10 is enabling asyncronously reading and writing JSON with JsonReader and JsonWriter, and asyncronously loading JObject, JArray and friends.

Async support means that reading or writing JSON to the file system or network will never block while waiting on IO. Client applications will be more responsive and web applications more scalable.

JArray largeJson;

// read asynchronously from a file
using (FileStream asyncFileStream = new FileStream(@"large.json", FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true))
{
largeJson = await JArray.LoadAsync(new JsonTextReader(new StreamReader(asyncFileStream)));
}

JToken user = largeJson.SelectToken("$[?(@.name == 'Woodard Caldwell')]");
user["isActive"] = false;

// write asynchronously to a file
using (FileStream asyncFileStream = new FileStream(@"large.json", FileMode.Open, FileAccess.Write, FileShare.Write, 4096, true))
{
await largeJson.WriteToAsync(new JsonTextWriter(new StreamWriter(asyncFileStream)));
}

Although it looks simple on the surface, adding async support to Json.NET was a huge task. Special thanks to Jon Hanna for contributing most of this work.

Performance

Json.NET now supports reading double and decimal values without internally converting the value to a string first. In addition to a small performance boost when deserializing double and decimal values, not creating a string for each double and decimal means less garbage for the garbage collector to clean up.

Obsoleting and removing

In an effort to slim down Json.NET the BSON functionality has been marked as obsolete. A Newtonsoft.Json.Bson package is on NuGet and contains a copy of BsonReader and BsonWriter. Obsolete classes in Newtonsoft.Json will eventually be removed after a few major versions.

Some previously obsoleted types and methods have been removed in Json.NET 10. These APIs aren't commonly used by end users, and all have been obsolete for multiple major versions. Check the detailed release notes below for more information.

Finally the Portable Class Library assembly that targets .NET 4 has been removed from the NuGet package.

And lots more

TypeConverters, BigInteger, ISerializable and XmlDocument are now supported in .NET Core applications, there have been multiple improvements to JSONPath querying of JObject/JArray, dozens of typos have been fixed in Json.NET's documentation, and many, many bugs have been reported and fixed across every part of Json.NET.

Changes

Here is a complete list of what has changed since Json.NET 9.0 Release 1.

  • New feature - Added async read support to JsonReader
  • New feature - Added async write support to JsonWriter
  • New feature - Added async support for loading JObject and JArray
  • New feature - Added non-allocating parsing of double and decimal values
  • New feature - Added support for TypeConverters to netstandard1.0+
  • New feature - Added support for BigInteger to netstandard1.3+
  • New feature - Added support for ISerializable to netstandard1.3+
  • New feature - Added support for XmlDocument to netstandard1.3+
  • New feature - Added support for SerializableAttribute and NonSerializedAttribute to netstandard1.3+
  • New feature - Added ISerializationBinder
  • New feature - Added SerializationBinder properties to JsonSerializer and JsonSerializerSettings
  • New feature - Added TypeNameAssemblyFormatHandling
  • New feature - Added TypeNameAssemblyFormatHandling properties to JsonSerializer and JsonSerializerSettings
  • New feature - Added support for root object selector in JSONPath filters
  • New feature - Added support for multiple names in JSONPath scan filter
  • New feature - Added support for any combination of paths and values in JSONPath filter expressions
  • New feature - Added support for extension data names to NamingStrategy
  • New feature - Added ProcessExtensionDataNames flag to NamingStrategy
  • New feature - Added JsonWriter.AutoCompleteOnClose to control whether JSON is auto-completed on JsonWriter.Close
  • New feature - Added JsonReaderException constructor with path, line number, line position
  • New feature - Added JsonWriterException constructor with path
  • New feature - Added JsonReader.SetToken method overload with option not to update position array index
  • New feature - Added support for automatically calling single constructor on immutable structs
  • Change - Removed .NET 4 portable class library target from NuGet package
  • Change - Removed obsolete JsonConverter.GetSchema method
  • Change - Removed obsolete constructor from DefaultContractResolver
  • Change - Removed obsolete async methods from JsonConvert
  • Change - Removed obsolete OnDeserialized, OnDeserializing, OnSerialized, OnSerializing, OnError from JsonContract
  • Change - Removed obsolete JsonDictionaryContract.PropertyNameResolver
  • Change - Removed obsolete ConstructorParameters, OverrideConstructor, ParametrizedConstructor from JsonObjectContract
  • Change - Obsoleted TypeNameAssemblyFormat properties on JsonSerializer and JsonSerializerSettings
  • Change - Obsoleted SerializationBinder
  • Change - Obsoleted Binder properties on JsonSerializer and JsonSerializerSettings
  • Change - Obsoleted FormatterAssemblyStyle in non-full .NET targets
  • Change - Obsoleted Newtonsoft.Json.Bson (moved to new NuGet package)
  • Change - Improved constructor parameter binding on .NET Core and portable builds
  • Change - Improved error when attempting to convert root JSON object property to an XML attribute
  • Change - Changed exception thrown when parsing invalid Unicode escape sequence to JsonReaderException
  • Change - Changed StringEnumConverter.AllowIntegerValues to also reject reading integer strings
  • Change - Changed StringEnumConverter.AllowIntegerValues to also reject writing enum values with no name
  • Fix - Fixed JsonTextReader.ReadAsXXX methods not erroring on missing commas between values
  • Fix - Fixed error when serializing F# lists with F# 4.1+
  • Fix - Fixed StringEnumConverter reading specified enum names that contain a comma
  • Fix - Fixed using a TraceWriter with nullable bytes
  • Fix - Fixed deserializing null Regex values
  • Fix - Fixed deserializing DataTable with error handling
  • Fix - Fixed DynamicReflectionDelegateFactory creating typed value type constructors
  • Fix - Fixed deserializing with type naming and complex nested generic types
  • Fix - Fixed error when converting certain JSON to XML on .NET Core
  • Fix - Fixed error handling skipping reading the next object value
  • Fix - Fixed date XML precision when converting certain JSON to XML on portable builds
  • Fix - Fixed not serializing readonly properties as references if they have corresponding creator parameters
  • Fix - Fixed type name being written with nullable structs and TypeNameHandling.Auto
  • Fix - Fixed deserializing a duplicate dictionary key from a parameterized constructor
  • Fix - Fixed not erroring when deserializing incomplete JSON with a parameterized constructor
  • Fix - Fixed incorrectly parsing scan filter when name is quoted
  • Fix - Fixed return type for SByte and SByteNullable in JToken.ToObject
  • Fix - Fixed deserializing generic only IList types with a constructor override
  • Fix - Fixed null reference error with ReadAsBytes and an empty JSON object
  • Fix - Fixed StringEnumConverter when EnumMember defines members that differ only by case
  • Fix - Fixed serializing protected override properties
  • Fix - Fixed merging null with complex type and MergeNullValueHandling.Ignore
  • Fix - Fixed roundtripping double.MaxValue and float.MaxValue as dictionary keys
  • Fix - Fixed JsonValidatingReader not closing underlying reader
  • Fix - Fixed writing duplicate nulls to trace with TraceJsonWriter.WriteValue for object, Uri, byte[]
  • Fix - Fixed BsonWriter.WriteValue erroring for null Uri or byte[]
  • Fix - Fixed not calling nullable WriteValue overloads in TraceJsonWriter
  • Fix - Fixed serializer not throwing an error when there is a comment followed by additional content with CheckAdditionalContent
  • Fix - Fixed JObject/JArray Parse not throwing an error when there is a comment followed by additional content
  • Fix - Fixed deserializing non-string values in some XML nodes
  • Fix - Fixed converting XML to JSON when json:Array and xmlns:json attributes are used directly on the array's element
  • Fix - Fixed error when attempting to populate values into read-only collection after creating object from non-default constructor

Links

Json.NET GitHub Project

Json.NET 10.0 Release 1 Download - Json.NET source code and assemblies

View Details

Memory, Allocations and Performance

There is a big push across the .NET eco-system on performance. In modern .NET apps one of the biggest culprits of poor performance is allocating too many objects. The more objects and memory you allocate, the more the garbage collector needs to clean up. Best case garbage collection will slow your application; worst cause the app will halt execution until GC is finished. GC is a great way to kill pages per second on the server and frames per second on the client.

To reduce allocations and memory usage when serializing Json.NET 8.0 adds a new IArrayPool interface. Json.NET is already very lean when it comes to allocations, working with raw characters on array buffers instead of allocated strings, but those buffers can easily grow large, and a new buffer is created each time JSON is read or written. IArrayPool allows array buffers to be reused, similar to connection pooling with a database, or thread pooling in .NET.

public class JsonArrayPool : IArrayPool<char>

{

public static readonly JsonArrayPool Instance = new JsonArrayPool();

public char[] Rent(int minimumLength)

{

// get char array from System.Buffers shared pool

return ArrayPool<char>.Shared.Rent(minimumLength);

}

public void Return(char[] array)

{

// return char array to System.Buffers shared pool

ArrayPool<char>.Shared.Return(array);

}

}

The example implemention above uses the upcoming System.Buffers package to manage pooling. Using the array pool just involves setting a property on JsonTextReader/JsonTextWriter.

IList<int> value;

JsonSerializer serializer = new JsonSerializer();

using (JsonTextReader reader = new JsonTextReader(new StringReader(@"[1,2,3,4]")))

{

// reader will get buffer from array pool

reader.ArrayPool = JsonArrayPool.Instance;

value = serializer.Deserialize<IList<int>>(reader);

}

IArrayPool is a somewhat experimental feature. Unless you have extreme performance requirements or your own object pooling system already in-place you can wait until a default pool is automatically included with Json.NET.

JArray and Comments

Previously when loading JSON that contained comments into JArrays the comment would be added as an item in the JArray. This would be a common cause of errors: most developers would expect a commented out value in a JArray to disappear, instead it becomes a comment token, and an error would be thrown if the app looped over the array, casting its values.

In Json.NET 8.0 comments are ignored by default. If you want the old behaviour then set CommentHandling.Load on JsonLoadSettings.

Bug Fixes. Bug Fixes Everywhere.

There are two dozen minor bug fixes in Json.NET 8.0, ranging from fixes serializing DataSets and XML (brave souls still use them), to serializing F# discriminated unions in UWP applications.

Changes

Here is a complete list of what has changed since Json.NET 7.0 Release 1.

  • New feature - Added IArrayPool and a setting on JsonTextReader and JsonTextWriter
  • New feature - Added JsonReader.ReadAsDouble
  • New feature - Added JsonLoadSettings and CommentHandling to control loading comments in LINQ to JSON
  • New feature - Added JsonLoadSettings.LineInfoHandling
  • New feature - Added support for JsonConstructorAttribute on list and dictionary collections
  • New feature - Added support for deserializing string to Version
  • New feature - Added ShouldDeserialize to JsonProperty
  • New feature - Added Required.DisallowNull
  • New feature - Added support for converting JSON to XML with invalid XML name chracters
  • New feature - Improved case-insensitive deserialization performance
  • New feature - Improved date parsing performance
  • Change - Changed ReadAsDateTime, ReadAsDateTimeOffset, ReadAsBytes, ReadAsString, ReadAsInt32 on JsonReader from abstract to virtual
  • Change - Changed parsing JArrays to not include comments by default
  • Change - Changed JTokenWriter to use the last property instead of erroring when there are duplicate property names
  • Change - Changed Uri JValues to use OriginalString when written to JSON
  • Change - Changed DateTimeOffset JValues to return TypeCode.Object from IConvertible.GetTypeCode()
  • Fix - Fixed converting JSON metadata array value to XML
  • Fix - Fixed not including line information with some XML conversion errors
  • Fix - Fixed error when writing certain JSON with escaped characters
  • Fix - Fixed PopulateObject error when JSON starts with a comment
  • Fix - Fixed incorrect IJsonLineInfo line position after the first line
  • Fix - Fixed JSONPath when querying against Uri, Guid and Date values
  • Fix - Fixed JsonReader.Path when the path is escaped
  • Fix - Fixed writing JRaw twice when a TraceWriter is set
  • Fix - Fixed getting the wrong value when reading certain large integers
  • Fix - Fixed deserializing DataSet with a null DataTable
  • Fix - Fixed deserializing a null DataSet
  • Fix - Fixed error when serializing F# discriminated unions in Windows Store apps
  • Fix - Fixed error serializing some types when there are conflicting interface properties
  • Fix - Fixed error when settings ReferenceResolver is set to null
  • Fix - Fixed DateTimeZoneHandling not being used when writing DateTime dictionary keys
  • Fix - Fixed bug when converting an integer JValue to a nullable enum
  • Fix - Fixed converting null string JValue to XML
  • Fix - Fixed Mono generic class private field serialization bug
  • Fix - Fixed error when deserializing ignored property with mismatched type
  • Fix - Fixed deserializing to a type when setting JToken extension data
  • Fix - Fixed setting default values onto properties already set in constructor
  • Fix - Fixed casting dynamic JValue to JToken
  • Fix - Fixed serializing non-zero based arrays
  • Fix - Fixed reading 24 hour midnight ISO dates

Links

Json.NET GitHub Project

Json.NET 8.0 Release 1 Download - Json.NET source code and assemblies

View Details

Documentation

The biggest improvements in Json.NET 7.0 have been to user documentation. The old documentation design with its 2003 era HTML (iframes + inline JavaScript) has been replaced with a lightweight, fast to load design.

Old and Busted (left) vs New Hotness (right):

It has been a couple of years since the docs were properly updated. New features added since then like extension data, annotations and JSONPath now have documentation and code samples. The new code samples brings the total up to 116!

Finally the documentation has been professionally proofread. My most embarrassing grammatical errors have been fixed.

NuGet Logo

Json.NET has a NuGet logo. Check it:

DiscriminatedUnionConverter performance improvements

Json.NET’s F# discriminated union support has been rewritten. Serializing very large collections of large discriminated unions was noticeably slow. The new implementation caches reflection and type data, and significantly improves performance.

That’s a 3200% improvement. If you’re using F# then you don’t need to do anything other than update Json.NET.

And everything else

Json.NET 7.0 includes 30 changes from 6 months of user feature requests and bug reports.

Changes

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

  • New feature - DiscriminatedUnionConverter performance improvements
  • New feature - Added JsonRequiredAttribute
  • New feature - Added JsonSerializerSettings.ReferenceResolverProvider property
  • New feature - Added DefaultContractResolver.ResolveDictionaryKey
  • New feature - Added JsonDictionaryContract.DictionaryKeyResolver
  • New feature - Added support for reading GUID strings as bytes in JsonTextReader
  • New feature - Added EqualityComparer to JsonSerializer
  • Change - Changed reading GUIDs as bytes to only support 00000000-0000-0000-0000-000000000000 format
  • Change - Renamed aspnetcore50 target to dnxcore50
  • Change - Marked JsonSchema as obsolete
  • Change - Marked DefaultContractResolver(bool) as obsolete
  • Change - Marked JsonSerializerSettings.ReferenceResolver as obsolete
  • Change - Marked JsonDictionaryContract.PropertyNameResolver as obsolete
  • Fix - Fixed deserializing empty strings in Hashtables
  • Fix - Fixed incorrect JTokenReader.Path in certain situations
  • Fix - Fixed error when serializing certain objects in medium trust
  • Fix - Fixed deserializing large nullable UInt64 values
  • Fix - Fixed writing large UInt64 JValues
  • Fix - Fixed converting unmatched namespace prefixes in JSON to XML
  • Fix - Fixed IsoDateTimeConverter on DateTime properties with DateTimeFormatHandling.DateTimeOffset
  • Fix - Fixed preserving object references with read only properties
  • Fix - Fixed error when deserializing large JSON integers to XML
  • Fix - Fixed serializing extension data properties with no setter
  • Fix - Fixed serializing discriminated unions with type name or reference tracking enabled
  • Fix - Fixed DataTableConverter not using JsonSerializer settings
  • Fix - Fixed resolving properties from nested interfaces
  • Fix - Fixed deserializing classes derived from ConcurrentDictionary
  • Fix - Fixed passing default values to constructors
  • Fix - Fixed serializing root references from JsonConverters
  • Fix - Fixed empty strings coerced to null not erroring with Required.Always
  • Fix - Fixed invalid Required.Always error with constructor property name casing
  • Fix - Fixed empty string coerce check with Required.Always and constructor

Links

Json.NET GitHub Project

Json.NET 7.0 Release 1 Download - Json.NET source code and assemblies

View Details

Annotations

This release of Json.NET adds annotations to LINQ to JSON. Annotations allow you to associate arbitrary objects with LINQ to JSON JObjects, JArrays and JValues.

Annotations aren’t part of the JSON specification; they aren’t read from JSON or written to JSON. Annotations are for use within an application.

JObject o = JObject.Parse(@"{

'name': 'Bill G',

'age': 58,

'country': 'United States',

'employer': 'Microsoft'

}");

o.AddAnnotation(new HashSet<string>());

o.PropertyChanged += (sender, args) => o.Annotation<HashSet<string>>().Add(args.PropertyName);

o["age"] = 59;

o["employer"] = "Bill & Melinda Gates Foundation";

HashSet<string> changedProperties = o.Annotation<HashSet<string>>();

// age

// employer

In this example we use annotations to track changes to a JObject. First a set of strings for is associated with a JObject using annotations. The PropertyChanged event is then used to add a property name to the set whenever its value is changed. The JObject’s changed properties are now easily accessible anywhere in your application from the JObject.

Changes

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

  • New feature - Added Annotations to LINQ to JSON
  • New feature - Added DescendantsAndSelf method to JObject and JArray
  • New feature - Added AncestorsAndSelf method to JToken
  • New feature - Added support for tracking references in ISerializable objects
  • New feature - Added CurrentToken to JTokenReader
  • New feature - Added CurrentToken to JTokenWriter
  • New feature - Added WriteToken(JsonToken, object) to JsonWriter
  • Fix - Fixed deserializing null values onto JObject and JArray properties
  • Fix - Fixed error when extension data bag doesn't inherit from Dictionary
  • Fix - Fixed deserializing complex values inside multi-dimensional arrays
  • Fix - Fixed serialization settings not being used when deserializing F# unions
  • Fix - Fixed MetadataTypeAttribute not being found on some platforms
  • Fix - Fixed line breaks in exception messages to use Environment.NewLine
  • Fix - Fixed deserializing certain XElements with comments
  • Fix - Fixed casting JValues with a negative value to a nullable SByte

Links

Json.NET GitHub Project

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

View Details

ASP.NET CoreCLR

Json.NET now supports running on the ASP.NET CoreCLR, a coming soon server optimized CLR for running applications in the cloud.

Today, you run ASP.NET using the same CLR that desktop apps use. We’re adding a cloud-optimized (my cloud, your cloud, their cloud - server stuff) version optimized for server scenarios like low-memory and high-throughput.

ASP.NET vNext will let you deploy your own version of the .NET Framework on an app-by-app-basis. One app with new libraries can’t break an app next door with a different version. Different apps can even have their own cloud-optimized CLR of their own version. The CLR and cloud-optimized libraries are NuGet packages!

Bin deploy ASP.NET to a Mac or Linux server? Sign. Me. Up. Find out more about the ASP.NET CoreCLR and ASP.NET vNext here.

Memory Usage Optimizations

This release of Json.NET optimizes memory usage, in particular heap allocations when reading and writing JSON.

Json.NET has always been memory efficient, streaming the reading and writing large documents rather than loading them entirely into memory, but I was able to find a couple of key places where object allocations could be reduced. Deserialization saw the biggest improvement with about a 35% decrease in allocations. Less allocations, less garbage collection. Less garbage collection, more requests per second.

The before memory timeline when deserializing a 5 megabyte JSON file:

And the after timeline:

Grey is unmanaged memory, blue is the Gen0 heap, red is Gen1, green is Gen2 and the profiler used is dotMemory.

For comparison, here is what JavaScriptSerializer looks like doing the same work:

JavaScriptSerializer only works with strings so the purple here is a 5 megabyte string being loaded into the large object heap. After the latest optimizations Json.NET allocates 8 times less memory than JavaScriptSerializer.

Changes

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

  • New feature - Added support for ASP.NET CoreCLR
  • New feature - Reduced memory allocations when reading and writing JSON
  • New feature - Added support for passing arguments to JsonConverters with JsonConvertAttribute
  • New feature - Added JsonConvert.ToString overload that takes a StringEscapeHandling parameter
  • Change - Omit fields array for F# discriminated union serialization when there are no fields
  • Change - Escape property names in path on readers/writers/tokens when a name contains special characters
  • Change - Provide line numbers for end tokens on JTokenReader
  • Fix - Fixed parsing in SelectToken when the path has an escaped property followed by an unescaped property
  • Fix - Fixed error when deserializing a GUID from certain BSON
  • Fix - Fixed null reference error when using a JEnumerable created with its default constructor
  • Fix - Fixed line breaks in exception messages to use Environment.NewLine
  • Fix - Fixed MetadataTypeAttribute reflection error on ASP.NET CoreCLR
  • Fix - Fixed immutable collections reflection error on ASP.NET CoreCLR

Links

Json.NET GitHub Project

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

View Details

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 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

View Details

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 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

View Details

JSONPath

Json.NET has supported basic path queries with SelectToken since forever. Json.NET 6.0 supes up SelectToken with full support for JSONPath, an XPath like querying language for JSON.

JObject o = JObject.Parse(@"{

""Manufacturers"": [

{

""Name"": ""Acme Co"",

""Products"": [

{

""Name"": ""Anvil"",

""Price"": 50

}

]

},

{

""Name"": ""Contoso"",

""Products"": [

{

""Name"": ""Elbow Grease"",

""Price"": 99.95

},

{

""Name"": ""Headlight Fluid"",

""Price"": 4

}

]

}

]

}");

// manufacturer with the name 'Acme Co'

var acme = o.SelectToken("$.Manufacturers[?(@.Name == 'Acme Co')]");

Console.WriteLine(acme);

// { "Name": "Acme Co", Products: [{ "Name": "Anvil", "Price": 50 }] }

A SelectTokens (plural) method has been added for returning a range of results from a JSONPath query.

// name of all products priced 50 and above

var pricyProducts = o.SelectTokens("$..Products[?(@.Price >= 50)].Name");

Console.WriteLine(pricyProducts);

// Anvil

// Elbow Grease

While LINQ to JSON offers more features and flexibility, JSONPath being string based makes it a good choice for persisting a queries or constructing dynamic queries.

F# Support

Json.NET 6.0 adds support for serializing and deserializing F# discriminated unions. There is nothing you need to do, F# discriminated unions will now Just Work.

type Shape =

| Rectangle of width : float * length : float

| Circle of radius : float

| Empty

[<EntryPoint>]

let main argv =

let shape1 = Rectangle(1.3, 10.0)

let json = JsonConvert.SerializeObject(shape1)

// {

// "Case": "Rectangle",

// "Fields": [

// 1.3,

// 10.0

// ]

// }

let shape2 = JsonConvert.DeserializeObject<Shape>(json)

Console.ReadKey() |> ignore

0

Assembly Version Happenings

Json.NET has had a static assembly version since 4.5 to avoid binding redirects. The problem with having a static assembly version is if a strongly named assembly with the same version number is found in the GAC, the GAC version will be used ahead for the /bin version. Some people have been encountering the problem that their applications break when someone else GACs an old Json.NET 4.5 on their server. I’m looking at you .NET CMSes.

The plan going forward is to increase the assembly version with major Json.NET releases. 6.0 Release 1 –> 6.0.0.0, 6.0 Release 2 –> 6.0.0.0, 7.0 Release 1 –> 7.0.0.0. Hopefully this will provide a balance between binding redirects and having the GAC ruin your day.

And The Rest

Tons of smaller features like parsing single line comments in JSON, reading multiple pieces of JSON content from a stream with one JsonReader, obsoleting of bad methods and lots of bug fixes.

Changes

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

  • New feature - Added support for JSONPath
  • New feature - Added support for serializing F# discriminated unions
  • New feature - Added support for deserializing nested DataTables and arrays in DataTables
  • New feature - Added support for reading multiple pieces of JSON with a JsonReader
  • New feature - Added AllowIntegerValues setting to StringEnumConverter
  • New feature - Added Decimal and DateTimeOffset constructors to JValue
  • New feature - Added support for reading JSON single line comments
  • New feature - Improved number parsing error messages
  • Change - Changed assembly version to 6.0.0.0
  • Change - .NET 4 Portable build targets MonoTouch and MonoDroid in NuGet package
  • Change - .NET 4 Portable build targets WP8 and SL5 instead of WP7 and SL4
  • Removed - DefaultMemberSearchFlags on DefaultContractResolver is obsolete
  • Removed - SerializeObjectAsync, DeserializeObjectAsync, PopulateObjectAsync on JsonConvert are obsolete
  • Fix - Fixed JObject ICustomTypeDescriptor properties returning incorrect value
  • Fix - Fixed error when casting dynamic base64 string to byte array
  • Fix - Fixed EntityKeyMemberConverter not using property name resolve
  • Fix - Fixed serializing JValues with readonly JsonConverters
  • Fix - Fixed formatting override on SerializeObject methods
  • Fix - Fixed error when wrapping an exception in a JsonConverter
  • Fix - Fixed using extension data with a non-default constructor
  • Fix - Fixed Uri serialization roundtripping with Uri.OriginalString
  • Fix - Fixed TypeNameHandling.Auto with JsonSerializer.Serialize inside a JsonConverter

Links

Json.NET GitHub Project

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

View Details

Getting this method not found error requires a rare combination of factors. If you haven’t seen it then feel free to ignore this blog post.

tl;dr; just tell me how to fix it

If you’re an end user and you get this error then make sure the version of Json.NET your application is loading is 5.0.8. If you have 5.0.8 in your \bin directory and you still get this error then check the GAC as well and update it if necessary.

If you’re a package author and a user reports getting this error from your code then downgrade the version of Json.NET your package is using to 5.0.4, recompile and release a new version of your package. If you can’t downgrade then another option is to add an IEnumerable cast to the erroring foreach loop.

foreach (JToken item in (IEnumerable<JToken>)array)

{

// stuff

}

Another option is to change the foreach loop to a for loop.

The Cause

In Json.NET 5.0.5 I changed JArray.GetEnumerator’s visibility from interface explicit to public. The side effect of GetEnumerator being public is the C# compiler will no longer add a IEnumerable cast to foreach loops. The cast is required when GetEnumerator is interface explicit and is only accessible when the object is cast to IEnumerable.

The error then occurs when an application or package that has a foreach loop over a JArray and is compiled with a public GetEnumerator is run using an older version of Json.NET, possible out of the GAC, where GetEnumerator is not public. Because there is no cast to IEnumerable then .NET can’t find the GetEnumerator method and an exception is thrown.

Json.NET 6.0 Long Term Fix

Rather than have this bug keep popping up for users I’m going to change JArray.GetEnumerator’s visibility back to interface explicit – the visibility it had in Json.NET 5.0.4 and earlier. Because this is a binary breaking change I’m going to increase Json.NET’s version number to 6.0.

Update: I have left GetEnumerator as public and updated Json.NET's assembly version number to 6.0.0.0 instead.

Sorry about this bug. It has sprung up because of a rare combination of factors and unfortunately Json.NET meets all of them.

View Details

Immutable Collections

The biggest new feature in Json.NET 5.0.7 is support for serializing and deserializing the offical new .NET Immutable Collections types.

string json = @"[

'Volibear',

'Teemo',

'Katarina'

]";

// deserializing directly to an immutable collection, what sorcery is this?!

ImmutableList<string> champions = JsonConvert.DeserializeObject<ImmutableList<string>>(json);

Console.WriteLine(champions[0]);

// Volibear

There is nothing you need to do to make immutable collection and Json.NET work together. Upgrade to Json.NET 5.0 Release 7, add the immutable collections NuGet package to your project and you can start using immutable collections with Web API, SignalR or directly from Json.NET like the example above.

Round-trip Extension Data

Extension data is now written when an object is serialized. Reading and writing extension data makes it possible to automatically round-trip all JSON without adding every property to the .NET type you’re deserializing to. Only declare the properties you’re interested in and let extension data do the rest.

public class CustomerInvoice

{

// we're only modifing the tax rate

public decimal TaxRate { get; set; }

// everything else gets stored here

[JsonExtensionData]

private IDictionary<string, JToken> \_additionalData;

}

string json = @"{

'HourlyRate': 150,

'Hours': 40,

'TaxRate': 0.125

}";

var invoice = JsonConvert.DeserializeObject<CustomerInvoice>(json);

// increase tax to 15%

invoice.TaxRate = 0.15m;

string result = JsonConvert.SerializeObject(invoice);

// {

// 'TaxRate': 0.15,

// 'HourlyRate': 150,

// 'Hours': 40

// }

Using extension data to round-trip JSON like this also means you don’t need to worry about third-party sources adding additional JSON because it will automatically be preserved when serializing/deserializing. Nifty.

If you don’t want extension data serialized (or deserialized) then disable that functionality by setting WriteData and ReadData properties on ExtensionDataAttribute to false.

Bug fixes

A couple of bugs crept into Json.NET after the flurry of releases earlier in the year. I have consulted with other developers and the consensus was that bugs are bad so this release fixes all known bugs.

Changes

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

  • New feature - Added support for Immutable Collections
  • New feature - Added WriteData and ReadData settings to DataExtensionAttribute
  • New feature - Added reference and type name handling support to extension data
  • New feature - Added default value and required support to constructor deserialization
  • Change - Extension data is now written when serializing
  • Fix - Added missing casts to JToken
  • Fix - Fixed parsing large floating point numbers
  • Fix - Fixed not parsing some ISO date timezones
  • Fix - Fixed schema validation of integer value when type was number
  • Fix - Fixed writing of IConvertible values when TypeCode returned was Object
  • Fix - Fixed serializing proxy objects with no default constructor

Links

Json.NET CodePlex Project

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

View Details

The rapid rise of mobile devices has created new opportunities for software developers: applications available anywhere and at any time, but has brought with it new problems: do I need to make a website and then a separate mobile application for every platform?

While iOS, Andriod and Windows Phone all use different programming languages, frameworks and tools for native apps, what is cross-platform between every device is HTML and JavaScript. Not only will an HTML5 mobile application allow us to target every platform, we can also reuse skills and knowledge from traditional website development.

In this blog post I will look at DevExtreme, a cross-platform HTML JS framework for Visual Studio, and in particular DevExtreme’s rich JavaScript charting widgets.

Installation and first impressions

DevExtreme has a great looking custom installer that is impressively simple and easy to use: choose trial installation, customize that install location if you want and you’re done.

After installation is complete you are presented with a dialog that serves as a hub to developers getting started with DevExtreme. Resources available to you include links a number of online demos, demo source code that was installed with DevExtreme and comprehensive documentation.

The online chart demos in the DevExtreme Data Visualization Gallery are particularly impressive. There are over 50 charts and their source code available which I found a great aid when using DevExtreme.

Getting Started

To try out DevExtreme’s charting widgets I’m going to create a simple cross-platform dashboard for the online game streaming website Twitch. My dashboard app will query Twitch’s REST API for data and graph the games being streamed and the number of viewers over time of the most popular streams.

Although I’m building my dashboard using ASP.NET MVC and Visual Studio, DevExtreme is a JavaScript framework and it can be used with any server side language and IDE.

Reference the DevExtreme CDN

The first step is adding the DevExtreme charting JavaScript file to the website. Fortunately DevExpress provides a CDN that hosts the JavaScript file we need.

```

```

The CDN returns a compressed, cached response to keep the website nice and fast.

Creating a Chart

DevExtreme’s data visualization widgets include line, bar, area and pie charts; circular and linear gauges; and range selectors. On the dashboard homepage I will create a pie chart displaying the most popular games being streamed on Twitch.

$("#gamesChartContainer").dxPieChart({

dataSource: [

{

game: "Test game 1",

viewers: 50,

channels: 1,

image: "test-game-1.jpg"

},

{

game: "Test game 1",

viewers: 50,

channels: 1,

image: "test-game-1.jpg"

}

],

series: [

{

argumentField: "game",

valueField: "viewers",

label: {

visible: true,

connector: {

visible: true,

width: 1

}

}

}

]

});

Call dxPieChart on the element you want the chart to appear in. Options are passed to the chart using a simple JSON object as an argument.

Fetching Data from Twitch.tv

Right now the pie chart is displaying static data. To bring in some real world data we’ll call Twitch.tv’s REST API. Because their API supports JSONP we can call the services directly from JavaScript using jQuery.

var ds = [];

$.getJSON("https://api.twitch.tv/kraken/games/top?callback=?", function (json) {

for (var i = 0; i < json.top.length; i++) {

ds.push({

game: json.top[i].game.name,

viewers: json.top[i].viewers,

channels: json.top[i].channels,

image: json.top[i].game.box.large

});

}

});

Once you have your data ready just include it in the options when initializing the chart.

Interactive Chart

The DevExtreme chart widgets have extensive options for hooking into client side events. To add a tooltip and click action to each game in the pie chart just wire up some functions to the tooltip and pointClick properties when initializing the chart.

tooltip: {

enabled: true,

customizeText: function () {

var game = ds[this.point.index];

return game.channels + ' streams, ' + game.viewers + ' viewers';

}

},

pointClick: function (p) {

var game = ds[p.index];

$("#gameContainer").html("<img class='game-image' src='" + game.image + "'/>");

},

Creating a Dynamically Updating Chart

The second chart we’ll create for the dashboard application is an area graph over viewers over time for a video game stream. The chart will start out without any data but every couple of seconds we’ll call a Twitch API to return the viewer count and dynamically update the graph with the new data.

$("#streamChartContainer").dxChart({

title: "Viewers",

commonSeriesSettings: {

type: "splineArea",

argumentField: "date"

},

series: [

{ valueField: "viewers", name: "Viewers" }

],

argumentAxis: { valueMarginsEnabled: false },

legend: { visible: false },

animation: { enabled: false }

});

Note that no data source has be included in the code above. Data will be retrieved from the Twitch API and set against the chart dynamically.

var dataSource = [];

function getStreamData() {

$.getJSON("https://api.twitch.tv/kraken/streams/" + name + "?callback=?", function (json) {

var viewers = json.stream.viewers;

dataSource.push({

date: new Date(),

viewers: viewers

});

$('#streamChartContainer').dxChart('option', 'dataSource', dataSource);

});

}

setInterval(function () {

getStreamData();

}, 5000);

Every 5 seconds the browser will poll the server for the current viewers, add the count and date to the data collection and then update the chart with the data collection as an argument.

Wrapping Up

I found the chart widgets in DevExtreme to be fast to setup and easy to use while still offering a lot of power for customization.

My small application has barely scratched the surface here of what the chart widgets offer, let alone the other features included in DevExtreme. If you’re looking to building a cross-platform multi-device application then DevExtreme is definitely worth a look.

Click here to download the Twitch Dashboard application source code

Disclosure of Material Connection: I received one or more of the products or services mentioned above for free in the hope that I would mention it on my blog. Regardless, I only recommend products or services I use personally and believe my readers will enjoy. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: Guides Concerning the Use of Endorsements and Testimonials in Advertising.

View Details

The big new feature in this release is a Json.NET plugin for Glimpse. For anyone not familiar with Glimpse it is an open source diagnostics tool for ASP.NET, bringing the server-side information of a webpage into the browser. It is very useful and takes just a couple of minutes to get running.

The Glimpse Json.NET plugin adds a JSON tab to the Glimpse UI with information about each time Json.NET is used on the server, including:

  • Serialized type
  • Time taken
  • Any errors (with stack trace)
  • The complete JSON document

Being able to see the complete JSON document that Json.NET serialized or deserialized will be particularly useful when debugging unexpected results.

The plugin also adds Json.NET events to the Glimpse timeline tab. The timeline tab is lets you see when and where Json.NET is used in a request. In the example below JSON is deserialized in the ASP.NET MVC controller action and then re-serialized in the Razor view.

Today all calls to SerializeObject/DeserializeObject will automatically show up in Glimpse and going forward the frameworks that use Json.NET should also start appearing. Making all JSON actions on the server (deserializing the JSON request, serializing the JSON response, calls to JSON services like Web API/Facebook/Twitter, etc) visible in the browser for debugging without digging into tools like Fiddler will be very useful.

Download the Json.NET Glimpse plugin off NuGet now:

Changes

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

  • New feature - Added serialized/deserialized JSON to verbose tracing
  • New feature - Added support for using type name handling with ISerializable content
  • Fix - Fixed not using default serializer settings with primitive values and JToken.ToObject
  • Fix - Fixed error writing BigIntegers with JsonWriter.WriteToken
  • Fix - Fixed serializing and deserializing flag enums with EnumMember attribute
  • Fix - Fixed error deserializing interfaces with a valid type converter
  • Fix - Fixed error deserializing ISerializable objects that also implement IConvertible
  • Fix - Fixed potential infinite loop when parsing unquoted JSON values

Links

Json.NET CodePlex Project

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

View Details

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

View Details

This release of Json.NET ships with many performance improvements, and is over 30% faster serializing and deserializing JSON compared to Json.NET 4.5.

Json.NET extends its performance lead over DataContractJsonSerializer and continues to be significantly faster than JavaScriptSerializer which is used by ASP.NET MVC.

Compiled Expressions on Windows 8 and Windows Phone 8

An additional performance improvement specific to Windows 8 and Windows Phone 8 is the switch from the serializer internally using latebound reflection to compiled expressions. In exchange for a small one off cost the first time a type is serialized, compiled expressions are considerably faster than latebound reflection and provide an additional speed boost to Json.NET on Win8 and WP8.

Changes

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

  • New feature - Added JsonWriter.SetWriteState to support inheritance from JsonWriter implementations
  • Change - Changed .NET 4.5 portable library and WinRT library to use compiled expressions reflection
  • Fix - Fixed error serializing non-generic types that implement IEnumerable

Links

Json.NET CodePlex Project

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

View Details

New and Updated Libraries

In Json.NET 5.0 there are a bunch of library version changes:

  • Added .NET 4.5 library
  • Added portable library targeting .NET 4.5 + WP8 + Win8
  • Removed the Silverlight library.
  • Removed the Windows Phone library

Upgrading library versions allows Json.NET to support new .NET features such as dynamic and async across more platforms.

A baseline portable class library still supports all platforms (.NET 4 + WP7 + SL5 + Win8) so have no fear Silverlight and Windows Phone developers, even though the dedicated libraries have been removed you can continue use the latest version of Json.NET on Silverlight/Windows Phone with a portable class library.

Note that the assembly version number of Json.NET 5.0 hasn't changed and is still 4.5.0.0 to avoid assembly redirect issues. Read more about assembly version numbers here.

Serializing NaN and Infinity Floating Point Values

Json.NET no longer serializes NaN and positive and negative infinity floating point values as symbols, which is invalid JSON. With 5.0 the new default is to serialize those values as strings, e.g. "NaN" instead of NaN. There is no change to serializing normal floating point numbers.

A FloatFormatHandling setting has been added so you can control how NaN and infinity values are serialized.

string json;

IList<double> d = new List<double> {1.1, double.NaN, double.PositiveInfinity};

json = JsonConvert.SerializeObject(d);

// [1.1,"NaN","Infinity"]

json = JsonConvert.SerializeObject(d, new JsonSerializerSettings {FloatFormatHandling = FloatFormatHandling.Symbol});

// [1.1,NaN,Infinity]

json = JsonConvert.SerializeObject(d, new JsonSerializerSettings {FloatFormatHandling = FloatFormatHandling.DefaultValue});

// [1.1,0.0,0.0]

BigInteger and Read-Only Collections

Json.NET 5.0 adds support for BigInteger. Now when reading and writing JSON there is no limit on the maximum size of integers Json.NET can handle.

There is also support for read-only collection interfaces (IReadOnlyList and IReadOnlyDictionary) which were added in .NET 4.5. As long as there is an IEnumerable constructor then Json.NET will deserialize to the read-only collection for you.

string json = @"[

9000000000000000000000000000000000000000000000001

]";

var l = JsonConvert.DeserializeObject<IReadOnlyList<BigInteger>>(json);

BigInteger nineQuindecillionAndOne = l[0];

// 9000000000000000000000000000000000000000000000001

*Performance*

There are many performance and memory improvements in Json.NET 5.0, especially when serializing and deserializing collections, and Json.NET in Windows 8 Store apps.

Changes

Here is a complete list of what has changed since Json.NET 4.5 Release 11.

  • New feature - Added .NET 4.5 library
  • New feature - Added portable library targeting .NET 4.5, Win8, WP8
  • New feature - Added Path to JToken
  • New feature - Added BigInteger support
  • New feature - Added IReadOnlyCollection and IReadOnlyDictionary support
  • New feature - Added FloatFormatHandling to JsonWriter/JsonSerializer/JsonSerializerSettings
  • New feature - Added DateFormatString to JsonWriter/JsonSerializer/JsonSerializerSettings
  • New feature - Added support for multiple serialization events and use base type serialization events
  • New feature - Added DeserializeAnonymousType overload with JsonSerializerSettings
  • New feature - Added support for specifying root type when serializing JSON with TypeNameHandling.Auto
  • New feature - Added support for creating lists and dictionaries with an IEnumerable constructor
  • New feature - Added IConvertible support to JValue
  • New feature - Added support for serializing custom IConvertible values
  • New feature - Added support for deserializing IList
  • New feature - Added support for converting byte array JValues to Guid
  • New feature - Added support for deserializing byte arrays to Guid
  • Change - NaN and Infinity floating point values are serialized as strings by default
  • Change - Minor breaking changes to JsonSchema type
  • Change - Upgraded Windows Phone assembly to WP8
  • Change - DateTime IDictionary keys are now serialized in ISO date format
  • Change - DataContractAttribute is no longer inherited to match DataConctractSerializer behavior
  • Change - StringEnumConverter converts empty strings to null for nullable enums
  • Change - Guids serialize to a binary UUID in BSON instead of a string
  • Remove - Removed SL4 library
  • Remove - Removed WP7 library
  • Fix - Fixed JTokenWriter returning a null reference
  • Fix - Fixed static fields to no longer be included with fields serialization
  • Fix - Fixed recursively reading type wrapper objects when deserializing
  • Fix - Fixed incorrect namespace when converting XML to JSON
  • Fix - Fixed poor performance when serializing/deserialize dynamic objects
  • Fix - Fixed StringEnumConverter to throw JsonSerializerException on error
  • Fix - Fixed hidden properties not being serialized

Links

Json.NET CodePlex Project

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

View Details

I do a lot of Azure development. While it is a great platform for setting up new environments, scaling instances and simple deployments; monitoring applications in Azure is difficult. It is a remote environment and because of the way Azure abstracts hosting for you there is no option to install your own software on the server.

Foglight for Azure Apps is a hosted service that sets up gathering information from Windows Azure for you. In this blog post I'm going to try out Foglight with a demo application I've put together for simulating a broken website (demo source code available at the end of the blog post).

Getting Started

Setting up Foglight for Azure Apps is really simple. Foglight has two configuration methods for adding an Azure deployment: manual configuration where you manually add details about each deployment you want to monitor, and automatic discovery where Foglight retrieves that information from Azure for you. I'm going to step through using the automatic discovery wizard.

With Foglight automatic discovery the only information you need is your role’s Azure Subscription ID. Subscription IDs can be found in the Windows Azure Management Portal by browsing to Settings -> Management Certificates.

The next step after copy/pasting your Subscription ID is to add a management certificate from Foglight to Azure. The download link for the certificate is in the wizard and it is uploaded in the same place where you got your Subscription ID.

Finally select the deployment you want to monitor and you’re finished.

Monitoring

The core of Foglight for Azure Apps are the monitors it provides to measure the health of your application. The first page you’ll come upon after setup is the dashboard which provides a nice summary of the state of your application. From this screen or from the menu you can drill into more detail about each monitor.

The availability page shows you whether your application is accessible from various locations around the world – useful for times when a user or users from a country report they can’t access your application. In the screenshot above I've activated server errors on my demo website which you can see showing up in orange in the availability graphs.

The health page lets you view health details about individual rolls in your application. Here you can see details like CPU, memory and disk usage, and HTTP traffic and bandwidth being used by each role. One nice feature here is Foglight aggregates everything together and provides an indication of whether the application is healthy or not. Seeing the health of an application in a graph over time lets you match user reported errors with past server problems. In the screenshot above I've active high CPU and memory usage in my demo application.

The services page shows the status of the Windows Azure services your application depends on (e.g. compute, databases, storage) in your application's region and the status of worldwide services (e.g. management portal, CDN). This is a useful tool when debugging a broken application to double check whether the issue is yours or is being caused by a problem in Azure infrastructure.

The top URLs page shows what URLs in an application are creating problems. URLs can either be the slowest pages in your application or the pages with the highest number of 404 and server errors.

Configuring Health and Alerts

An awesome feature of Foglight is the control you have over configuring health thresholds and sending alerts.

Once you're happy with the health thresholds (the screenshot above shows the default) you can then configure at what health level alerts should be emailed and who they should be emailed to.

Health alerts are one of the most important features when monitoring, letting you know about problems as soon as they happen rather than waiting until someone look at Foglight or hear about errors from your users.

One thing I’ve done in the past with errors is to send an SMS message to my phone. Foglight doesn’t have built in SMS support but it is simple to set up using IFTTT.

Wrapping Up

I found Foglight's monitoring easy to understand and fast to update. Really impressive is how simple Foglight is to setup, taking just a couple of minutes and requiring no changes to your application. Finally the Foglight’s health alerts will ensure you know about critical issues as they happen.

If you're deploying applications to Azure and it is important they are rock solid then I recommend you check Foglight for Azure Apps out.

Click here to download the Windows Azure JsonFormat application source code

Disclosure of Material Connection: I received one or more of the products or services mentioned above for free in the hope that I would mention it on my blog. Regardless, I only recommend products or services I use personally and believe my readers will enjoy. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: Guides Concerning the Use of Endorsements and Testimonials in Advertising.

View Details

Serialization Tracing

The major new feature this release is serialization tracing. Using the ITraceWriter interface you can log and debug what is happening inside the Json.NET serializer when serializing and deserializing JSON.

Staff staff = new Staff();

staff.Name = "Arnie Admin";

staff.Roles = new List<string> { "Administrator" };

staff.StartDate = DateTime.Now;

ITraceWriter traceWriter = new MemoryTraceWriter();

JsonConvert.SerializeObject(

staff,

new JsonSerializerSettings { TraceWriter = traceWriter, Converters = { new JavaScriptDateTimeConverter() } });

Console.WriteLine(traceWriter);

// 2012-11-11T12:08:42.761 Info Started serializing Newtonsoft.Json.Tests.Serialization.Staff. Path ''.

// 2012-11-11T12:08:42.785 Info Started serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path 'StartDate'.

// 2012-11-11T12:08:42.791 Info Finished serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path 'StartDate'.

// 2012-11-11T12:08:42.797 Info Started serializing System.Collections.Generic.List`1[System.String]. Path 'Roles'.

// 2012-11-11T12:08:42.798 Info Finished serializing System.Collections.Generic.List`1[System.String]. Path 'Roles'.

// 2012-11-11T12:08:42.799 Info Finished serializing Newtonsoft.Json.Tests.Serialization.Staff. Path ''.

Json.NET has two implementations of ITraceWriter: MemoryTraceWriter which keeps messages in memory for simple debugging like the example above, and DiagnosticsTraceWriter which writes messages to any System.Diagnostics.TraceListeners your application is using.

To write messages using your existing logging framework implement a custom version of ITraceWriter.

Read more about trace writing here: Debugging with Serialization Tracing

JSON String Escaping

By default Json.NET only escapes control characters like new line when serializing text. New in this release is the StringEscapeHandling property on JsonTextWriter. Using StringEscapeHandling you can choose to escape HTML characters (<, >, &, ', ") or escape all non-ASCII characters.

JToken.ToObject Performance

The LINQ to JSON JToken class has a ToObject method on it for converting the JSON token to a .NET type. In previous versions of Json.NET this method always used the JsonSerializer behind the scenes to do the conversion which was unnecessary for converting simple types like strings, numbers, booleans, dates, etc.

Json.NET 4.5 Release 11 now checks whether the object being converted to is a simple type and if so it skips using the JsonSerializer. The end result is ToObject is now 400% faster for most types.

Changes

Here is a complete list of what has changed since Json.NET 4.5 Release 10.

  • New feature - Added ITraceWriter, MemoryTraceWriter, DiagnosticsTraceWriter
  • New feature - Added StringEscapeHandling with options to escape HTML and non-ASCII characters
  • New feature - Added non-generic JToken.ToObject methods
  • New feature - Deserialize ISet properties as HashSet
  • New feature - Added implicit conversions for Uri, TimeSpan, Guid
  • New feature - Missing byte, char, Guid, TimeSpan and Uri explicit conversion operators added to JToken
  • New feature - Special case so Version type is correctly deserialized
  • Change - Silverlight and Windows Phone assemblies in NuGet are strong named again
  • Change - Improved CamelCasePropertyNamesContractResolver camel casing property names
  • Change – Explicit JValue conversions are more flexible when converting values
  • Fix - Fixed QuoteChar not being used when writing DateTimes, TimeSpans, Uris and Guids
  • Fix - Fixed JValue constructors for Uri, TimeSpan, Guid assigning incorrect JTokenType
  • Fix - Fixed ReferenceLoopHandling not being used when serializing ISerializable and dynamic values
  • Fix - Fixed potential null reference error when getting attributes
  • Fix - Fixed .NET 2.0 build incorrectly referencing DateTimeOffset

Links

Json.NET CodePlex Project

Json.NET 4.5 Release 11 Download – Json.NET source code and assemblies