Skip to content

A comparison of Newtonsoft.Json and System.Text.Json

Jyoti Sharma Mar 15, 2021 9:16:20 AM

Microsoft released their new namespace System.Text.Json with .Net Core 3.0 in 2019 and many of you are considering migrating over from Newstonsoft.Json. Are there any advantages around performance or ease of use from using the newly added library from Microsoft? Or should you stick with the NewtonSoft library? Speaking from experience, we wanted to share with you what we learned in the process of migrating from one library to the other, as well as provide a bit of a comparison between Newtonsoft.Json and System.Text.Json.

Why a new System.Text.Json library?

Newtonsoft.Json, our serializer friend, has been around for a very long time. It’s the library which is pretty much used by almost every .Net developer for serializing to and deserializing from JSON. Yet, Microsoft shipped a new namespace System.Text.Json with .Net Core 3.0 in the year 2019. So why a new JSON serializer?

(This library is included in runtime for .Net Core 3.x and .Net 5.0. For other frameworks, you need to install System.Text.Json nugget package)

The driving force behind introducing System.Text.Json was performance and security. While they tried packaging Newtonsoft.Json inside .Net, they had some difficulties. Microsoft also wanted to remove the Newtonsoft.Json dependency from ASP.Net Core 3.0.

Newtonsoft.Json Features supported by System.Text.Json

Let’s take a look at some of the Newtonsoft.Json features supported by System.Text.Json and those that are missing. For a complete list of features, visit Microsoft Documentation.

*Please note that the below comparison is done based on .Net framework 5.0.

  • Case insensitive deserialization:
    • By default, Newtonsoft.Json does case insensitive property name matching during deserialization whereas System.Text.Json does case sensitive matching (with exception in ASP.Net core where you don’t need to do anything to achieve behavior like Newtonsoft.Json).
    • For case insensitive matching in System.Text.Json, set JsonSerializerOptions.PropertyNameCaseInsensitive to true.
  • Allow comments and Trailing commas:
  • Minimal character escaping
    • When it comes to security, System.Text.Json wins the race. It escapes all non ascii and HTML sensitive characters by default to provide protection against cross site scripting attacks. On the other hand, Newtonsoft.Json is relatively less strict.
  • Maximum depth
    • System.Text.Json has a default depth limit of 64 (in ASP.Net Core, it is 32) opposed to Newtonsoft.Json which does not have any limit.
    • To change maximum depth limit in System.Text.Json, use JsonSerializerOptions.MaxDepth option.
  • Serialize and Deserialize fields  
    • Newtonsoft.Json serialize and deserialize fields by default. System.Text.Json does not have a default support for serializing and deserializing fields.
    • Use the JsonSerializerOptions.IncludeFields global setting or the [JsonInclude] attribute in System.Text.Json to achieve this behavior.
  • Null value handling
  • Allow numbers in quotes

Missing features in System.Text.Json

  • If you rely on built in types like Datatable, DBNull, TimeSpan, TimeZoneInfo, BigInteger, etc., System.Text.Json does not support them by default. You will probably have to write a custom converter. For those cases, I would tend to stick with Newtonsoft.Json.
  • Polymorphic serialization and deserialization are not supported by default. System.Text.Json can do Polymorphic serialization to some extent but not deserialization. You need to write a custom converter for it.
  • System.Text.Json doesn't support attributes from System.Runtime.Serialization namespace,  such as DataMemberAttribute and IgnoreDataMemberAttribute. If you have used these attributes in your DTOs, it can take a lot of effort to change them during migration.
  • System.Text.Json does not allow property names without quotes, single quotes around string, and non-string JSON values for string properties.
  • System.Text.Json throws exception by default when a loop is encountered during serialization (imagine a case where you are serializing an object that contains two properties that contains a reference to the same object). There is no setting in System.Text.Json to exclude looping values during serialization. Newtonsoft.Json does so using ReferenceLoopHandling setting. To preserve references and handle circular references in System.Text.Json, set JsonSerializerOptions.ReferenceHandler to Preserve.

Performance Comparison

System.Text.Json library is focused on high performance. It is super-fast, and some people even think that it is two-times faster than Newtonsoft.Json, but this is not our experience , it totally depends on your scenario and payload.

I did a performance comparison test between System.Text.Json and Newtonsoft.Json and here are the results.

serialization performance

deserialization

Employee - a class with only 3 properties, Person - a class with 12 properties (with a couple of enums)

In first category, list contains one million instances of Employee class. In second category, list contains one million instances of Person class.

As can be seen above, the System.Text.Json is much faster than the Newtonsoft.Json.

To migrate or not

By now, you probably have an idea whether you want to go for migration or not.

Let’s sum up the whole thing in 2 main points.

  1. If you have used Newtonsoft.Json features in your existing projects that are missing in System.Text.Json or have heavily decorated your DTO’s with several attributes from Newtonsoft.Json, you will probably encounter many obstacles during migration.
  2. If you are starting a new project, I would recommend using System.Text.Json. Microsoft is constantly improving System.Text.Json and there has been significant improvements between .Net Core 3.1 and .Net 5.0 and Microsoft has already started planning for .Net 6.0.

 

Hope you enjoyed reading this article and that your decision to migrate or not migrate is a bit easier with this comparison of Newtonsoft.Json and SystemText.Json.

 

Other blog posts you may enjoy:

How to build web applications faster with Azure's Durable Functions

How to debug issues, directly in production, with Snapshot Debugger

5 ways to build application flexibility and efficiency