.NET Deserialization Cheat Sheet: Practical Guide for JSON & XML
This cheatsheet focuses on practical, modern, and secure deserialization in .NET, primarily using the recommended built-in System.Text.Json and the widely-used Newtonsoft.Json (Json.NET) library.
1. Modern JSON Deserialization (Recommended) 💡
Use the built-in library, System.Text.Json (part of the .NET framework since .NET Core 3.0), for superior performance and security by default.
Basic Usage
| Action | System.Text.Json Method (Namespace: System.Text.Json) | Example Code (C#) |
| String to Object | JsonSerializer.Deserialize<T>(string) | var obj = JsonSerializer.Deserialize<MyClass>(jsonString); |
| Stream to Object | JsonSerializer.DeserializeAsync<T>(Stream) | var obj = await JsonSerializer.DeserializeAsync<MyClass>(stream); |
| UTF-8 Bytes to Object | JsonSerializer.Deserialize<T>(ReadOnlySpan<byte>) | var obj = JsonSerializer.Deserialize<MyClass>(utf8Bytes); |
Key Configuration (JsonSerializerOptions)
| Option | Use Case | Example (C#) |
PropertyNameCaseInsensitive | Ignore case when matching JSON properties to C# properties. | options.PropertyNameCaseInsensitive = true; |
AllowTrailingCommas | Allows a trailing comma in JSON arrays and objects. | options.AllowTrailingCommas = true; |
ReadCommentHandling | Allows comments in the JSON input. | options.ReadCommentHandling = JsonCommentHandling.Skip; |
| Custom Converters | Handle custom formats like DateTimeOffset or polymorphic types safely. | options.Converters.Add(new MyCustomConverter()); |
Code Snippet (C#)
using System.Text.Json;
// Define your target DTO (Data Transfer Object)
public class UserData
{
public int Id { get; set; }
public string Name { get; set; }
}
public UserData DeserializeUser(string json)
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
try
{
// Deserialization with safe, built-in features
return JsonSerializer.Deserialize<UserData>(json, options);
}
catch (JsonException ex)
{
// Always handle malformed input
throw new Exception("Invalid JSON format.", ex);
}
}
2. Newtonsoft.Json (Json.NET) Deserialization
A highly feature-rich and flexible third-party library, common in older and complex projects.
Basic Usage
| Action | Newtonsoft.Json Method (Namespace: Newtonsoft.Json) | Example Code (C#) |
| String to Object | JsonConvert.DeserializeObject<T>(string) | var obj = JsonConvert.DeserializeObject<MyClass>(jsonString); |
| Stream/File | Use JsonSerializer.Create() with a JsonTextReader. | More verbose, see section 4 for safe streams. |
| To Dynamic Object | JsonConvert.DeserializeObject<dynamic>(string) | dynamic data = JsonConvert.DeserializeObject(jsonString); |
Key Configuration (JsonSerializerSettings)
| Setting | Use Case | SECURITY NOTE ⚠️ |
TypeNameHandling | Enables polymorphic deserialization (types are included in JSON). | Set to None (the default) to prevent RCE attacks from untrusted input. |
MissingMemberHandling | Specify behavior if JSON has fields missing in the C# class. | MissingMemberHandling.Ignore (default) or Error. |
ReferenceLoopHandling | Control how circular references are handled. | ReferenceLoopHandling.Ignore is common for deserializing. |
3. XML Deserialization
Used for SOAP, configuration, and data-sharing scenarios where JSON isn’t used.
Basic Usage
| Action | XmlSerializer Method (Namespace: System.Xml.Serialization) | Example Code (C#) |
| Stream/String to Object | XmlSerializer.Deserialize(TextReader) | var obj = (MyClass)serializer.Deserialize(reader); |
| Setup | Instantiate once per type. | var serializer = new XmlSerializer(typeof(MyClass)); |
XML Attributes
| Attribute | Use Case |
[XmlRoot("...")] | Specifies the XML root element name. |
[XmlElement("...")] | Maps a C# property to an XML element. |
[XmlAttribute("...")] | Maps a C# property to an XML attribute. |
[XmlIgnore] | Excludes a C# property from serialization/deserialization. |
4. Security & Best Practices 🛡️
The #1 Rule: NEVER deserialize untrusted data with formatters that include type information.
| Practice/Vulnerability | Actionable Steps |
| Vulnerable Formatters | 🛑 AVOID BinaryFormatter, SoapFormatter, LosFormatter, NetDataContractSerializer, ObjectStateFormatter. They are inherently unsafe with untrusted input and are marked obsolete/insecure by Microsoft. |
| JSON Type Handling | MUST ensure TypeNameHandling in Newtonsoft.Json is set to None (the default and safest value) for untrusted input. Other values can enable Remote Code Execution (RCE). |
| Input Validation | Always wrap deserialization in try-catch blocks (e.g., catching JsonException or InvalidOperationException). Validate the deserialized object’s property values after deserialization. |
| Type Restriction | Limit the types that can be deserialized. For System.Text.Json, this is secure by default (it only creates the target type). For XML, use a statically typed XmlSerializer(typeof(T)). |
| DoS Mitigation | Limit the maximum size of the input data (e.g., using JsonSerializerOptions.MaxDepth in System.Text.Json or custom stream reading size limits) to prevent memory exhaustion from oversized payloads. |
Safely Deserializing a Stream (Json.NET)
Using a StreamReader and a JsonTextReader is safer for large or unknown-size payloads.
using Newtonsoft.Json;
using System.IO;
public MyClass SafeDeserialize(Stream stream)
{
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
var serializer = new JsonSerializer
{
// Enforce security best practice
TypeNameHandling = TypeNameHandling.None
};
return serializer.Deserialize<MyClass>(jsonReader);
}
}
5. Advanced Customization & Annotations
Use C# attributes to customize the mapping between your class and the serialized data format.
| Library | JSON Attribute | XML Attribute | Purpose |
System.Text.Json | [JsonPropertyName("name")] | N/A | Specify a different JSON property name. |
[JsonIgnore] | N/A | Exclude a property from serialization/deserialization. | |
Newtonsoft.Json | [JsonProperty("name")] | N/A | Specify a different JSON property name. |
[JsonIgnore] | N/A | Exclude a property from serialization/deserialization. | |
System.Xml.Serialization | N/A | [XmlElement("...")] | Map to an XML element. |
| N/A | [XmlAttribute("...")] | Map to an XML attribute. |
