Upgrading to 5.0
Version 5.0 switches serialization from Json.NET to System.Text.Json with stock System.Text.Json behaviour. It’s a breaking release - but for most code the migration is one line.
The one line migration
If your models rely on the legacy Json.NET behaviour opt back in and you get the 4.x behaviour back exactly:
var config = new Config().UseNewtonsoftJson(); // optionally takes your JsonSerializerSettings
// Or when using IHttpClientFactory
services
.AddRestClient("MyClient", "https://dalsoft.co.uk")
.UseNewtonsoftJson();
The breaking changes
| 4.x (Json.NET) | 5.0 (System.Text.Json) |
|---|---|
[JsonProperty] honoured |
[JsonPropertyName] honoured |
| Case insensitive property matching | Case sensitive property matching |
| Lenient parsing (single quotes, NaN etc.) | Strict parsing - except trailing commas and comments which are still accepted |
| Failed typed casts throw the Json.NET exceptions | Failed typed casts throw System.Text.Json.JsonException |
SetJsonSerializerSettings(jsonSerializerSettings) |
Removed - use UseNewtonsoftJson(jsonSerializerSettings) |
Config.JsonSerializerSettings property |
Removed - use UseNewtonsoftJson(jsonSerializerSettings) |
Every row above goes back to the 4.x behaviour if you call UseNewtonsoftJson().
Watch out for case sensitive matching
This is the breaking change most likely to bite - models that only deserialized because Json.NET matched case insensitively will silently return null properties under System.Text.Json:
public class User
{
// jsonplaceholder returns "username" - Json.NET happily matched this case insensitively,
// System.Text.Json needs the name mapped
[JsonPropertyName("username")]
public string Username { get; set; }
}
If you want case insensitive matching back globally without opting in to Json.NET use SetJsonSerializerOptions(new JsonSerializerOptions { PropertyNameCaseInsensitive = true }).
What didn’t change
Everything else - the dynamic API, casting, the handler pipeline, the fluent chaining, IHttpClientFactory support - works exactly as it did in 4.x.
Version 5.0 also multi-targets .NET Standard 2.0 and .NET 8.0, and had a big performance pass - see Performance.