Using System.Text.Json to replace Newtonsoft's JSON package in .NET 3.0
Posted: (EET/GMT+2)
The new .NET Core 3.0 includes a new built-in JSON library called System.Text.Json. For most simple JSON serialization tasks, this means you no longer need to add the Newtonsoft.Json package to every project just to get JSON in or out.
Old code with Newtonsoft.Json often looks like this:
using Newtonsoft.Json;
Product product = new Product()
{
Id = 123,
Name = "Keyboard",
Price = 49.90m
};
string json = JsonConvert.SerializeObject(product);
Product? copy = JsonConvert.DeserializeObject<Product>(json);
The equivalent code with the new System.Text.Json namespace (no NuGet packages needed) looks like this:
using System.Text.Json;
Product product = new Product()
{
Id = 123,
Name = "Keyboard",
Price = 49.90m
};
string json = JsonSerializer.Serialize(product);
Product? copy = JsonSerializer.Deserialize<Product>(json);
Here is the model class:
public class Product
{
public int Id { get; set; }
public string? Name { get; set; }
public decimal Price { get; set; }
}
If you want formatted JSON, add serializer options:
JsonSerializerOptions options = new JsonSerializerOptions()
{
WriteIndented = true
};
string json = JsonSerializer.Serialize(product, options);
For Web APIs, camel case property names are common:
JsonSerializerOptions options = new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
string json = JsonSerializer.Serialize(product, options);
This produces property names such as id, name, and
price instead of Pascal-case Id, Name, and Price.
When reading JSON from external systems, it can also be useful to allow case-insensitive property matching:
JsonSerializerOptions options = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
};
Product? product = JsonSerializer.Deserialize<Product>(json, options);
If a JSON property has a different name than the C# property, use JsonPropertyName:
using System.Text.Json.Serialization;
public class Product
{
[JsonPropertyName("product_id")]
public int Id { get; set; }
[JsonPropertyName("product_name")]
public string? Name { get; set; }
public decimal Price { get; set; }
}
For small JSON documents where you do not want to create a model class, JsonDocument is useful:
using System.Text.Json;
string json =
"""
{
"id": 123,
"name": "Keyboard",
"price": 49.90
}
""";
using JsonDocument document = JsonDocument.Parse(json);
JsonElement root = document.RootElement;
int id = root.GetProperty("id").GetInt32();
string? name = root.GetProperty("name").GetString();
Console.WriteLine(id);
Console.WriteLine(name);
There is one important warning: System.Text.Json is not a perfect drop-in
replacement for Newtonsoft.Json.
Check carefully if your existing code uses Newtonsoft.Json features such as:
JObjectandJArray- custom converters
- dynamic JSON access
- advanced polymorphic serialization
- special date handling
- private setters or unusual object construction.
For new code and simple DTOs (Data Transfer Objects), System.Text.Json is a good default choice.
For existing applications with heavy Newtonsoft.Json usage, migrate one area at a time and keep tests around the JSON input and output.
In ASP.NET Core 3.0, System.Text.Json is the default JSON serializer. If an application still needs Newtonsoft.Json-specific behavior, Newtonsoft.Json support can still be added explicitly.
Good migration rule: replace simple serialization first, then review the complicated cases separately.
Happy serialization!