What it is
Json.NET (Newtonsoft.Json) is the long-established JSON library for .NET, with extensive customisation, LINQ to JSON and broad format tolerance.
Serialize and deserialize with static helpers, control behaviour with attributes or settings, and query loosely-structured documents with JObject and JToken.
Installation
dotnet add package Newtonsoft.JsonGetting started
The smallest useful thing you can do with it, and what each part means.
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
// Never enable TypeNameHandling on untrusted input — it is a
// remote code execution vector.
TypeNameHandling = TypeNameHandling.None,
};
var json = JsonConvert.SerializeObject(book, settings);
var back = JsonConvert.DeserializeObject<Book>(json, settings);var doc = JObject.Parse(payload);
string? title = (string?)doc["books"]?[0]?["title"];
// Query across the document without a matching class.
var recent = doc["books"]!
.Where(b => (int)b["year"]! > 1990)
.Select(b => (string)b["title"]!)
.ToList();Advanced usage
Where the library earns its place over a simpler alternative.
public class MoneyConverter : JsonConverter<Money>
{
public override void WriteJson(JsonWriter w, Money v, JsonSerializer s) =>
w.WriteValue($"{v.Amount}:{v.Currency}");
public override Money ReadJson(JsonReader r, Type t, Money existing,
bool hasExisting, JsonSerializer s)
{
var parts = ((string)r.Value!).Split(':');
return new Money(decimal.Parse(parts[0]), parts[1]);
}
}
[JsonConverter(typeof(MoneyConverter))]
public record Money(decimal Amount, string Currency);Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Unexpected character encountered while parsing
- The input is not JSON — often an HTML error page from a failed request. Check the status code before parsing.
- Self referencing loop detected
- A bidirectional entity relationship. Set ReferenceLoopHandling.Ignore, or serialise a DTO instead of the entity.
Best practices
- Never enable TypeNameHandling for data from outside your system.
- Prefer System.Text.Json for new code; it is faster and needs no dependency.
- Configure settings once and reuse them rather than passing them ad hoc.
- Use LINQ to JSON when the document shape is unknown; use typed models when it is not.
Background
Why it exists, and what it was reacting to.
Written by James Newton-King, Json.NET was the de facto standard for over a decade. System.Text.Json now ships with .NET and is faster, but Json.NET remains where flexibility matters more than throughput.
