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:
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
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:
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.
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.
.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
Changes
Here is a complete list of what has changed since Json.NET 11.0 Release 2.
Links
Json.NET GitHub Project
Json.NET 12.0 Release 1 Download - Json.NET source code and assemblies
.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
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
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.
Links
Json.NET GitHub Project
Json.NET 11.0 Release 1 Download - Json.NET source code and assemblies
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.
Links
Json.NET GitHub Project
Json.NET 10.0 Release 1 Download - Json.NET source code and assemblies
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.
Links
Json.NET GitHub Project
Json.NET 8.0 Release 1 Download - Json.NET source code and assemblies
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.
Links
Json.NET GitHub Project
Json.NET 7.0 Release 1 Download - Json.NET source code and assemblies
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.
Links
Json.NET GitHub Project
Json.NET 6.0 Release 7 Download - Json.NET source code and assemblies
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.
Links
Json.NET GitHub Project
Json.NET 6.0 Release 6 Download - Json.NET source code and assemblies
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.
Links
Json.NET GitHub Project
Json.NET 6.0 Release 4 Download - Json.NET source code and assemblies
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
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.
Links
Json.NET GitHub Project
Json.NET 6.0 Release 3 Download - Json.NET source code and assemblies
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.
Links
Json.NET GitHub Project
Json.NET 6.0 Release 1 Download - Json.NET source code and assemblies
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
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
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
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.
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.
Links
Json.NET CodePlex Project
Json.NET 5.0 Release 7 Download – Json.NET source code and assemblies
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.
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:
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.
Links
Json.NET CodePlex Project
Json.NET 5.0 Release 6 Download – Json.NET source code and assemblies
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.
Links
Json.NET CodePlex Project
Json.NET 5.0 Release 5 Download – Json.NET source code and assemblies
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.
Links
Json.NET CodePlex Project
Json.NET 5.0 Release 4 Download – Json.NET source code and assemblies
New and Updated Libraries
In Json.NET 5.0 there are a bunch of library version changes:
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
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.
Links
Json.NET CodePlex Project
Json.NET 5.0 Release 1 Download – Json.NET source code and assemblies
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.
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.
Links
Json.NET CodePlex Project
Json.NET 4.5 Release 11 Download – Json.NET source code and assemblies