How to ignore JSON deserialization errors in C#
By FoxLearn 3/13/2025 3:05:04 AM 23
Consider the following JSON. The second object has invalid data (can't convert string to float), which will result in deserialization failure:
[ { "Name": "Alice", "Salary": 50000.0 }, { "Name": "Bob", "Salary": "invalid" } ]
Using Newtonsoft.Json
, you can choose to ignore deserialization errors by passing an error handling lambda in the settings:
using Newtonsoft.Json; var employees = JsonConvert.DeserializeObject<List<Employee>>(employeeJson, new JsonSerializerSettings() { Error = (sender, error) => error.ErrorContext.Handled = true }); Console.WriteLine($"How many valid employees? {employees?.Count()}");
This will output:
How many valid employees? 1
In this case, all deserialization errors are ignored, and the object with the error is excluded. Therefore, the "invalid" entry (Bob) is removed from the result, leaving only valid entries in the list.
System.Text.Json Does Not Have This Functionality
System.Text.Json
does not currently support ignoring deserialization errors out-of-the-box. If you need this feature, I recommend using Newtonsoft.Json
. Alternatively, you'd have to implement a custom JSON converter to handle such errors manually.
What Happens When an Object Has an Error?
When an object encounters a deserialization error:
- The object with the error is excluded from the result.
- The parent object containing the error will also be excluded (recursively affecting the hierarchy).
- Arrays containing the faulty object will not be excluded entirely.
This is particularly useful when deserializing JSON arrays because each object in the array is independent. You can filter out faulty objects while retaining the valid ones.
It also allows you to avoid exceptions when deserializing a single object, especially if you do not want to wrap the deserialization in a try/catch
block.
Example - Child Object with an Error
Consider this array of employee data, where one employee has an invalid project ID:
[ { "Id": 101, "Project": { "Id": 1, "Name": "Project X" } }, { "Id": 102, "Project": { "Id": null, "Name": "Project Y" } } ]
For example, How you would deserialize and ignore errors:
var employees = JsonConvert.DeserializeObject<List<Employee>>(employeeJson, new JsonSerializerSettings() { Error = (sender, error) => error.ErrorContext.Handled = true }); Console.WriteLine($"Valid employees count: {employees?.Count()}");
This will output:
Valid employees count: 0
In this case, the child object (Project
) had an error (with a null
ID), which caused the parent object (Employee
) to be excluded, resulting in an empty list.
Example - Error in an Object Within an Array
Consider the following list of products where one item has a bad price:
[ { "ProductName": "Laptop", "Price": 1200.50 }, { "ProductName": "Phone", "Price": "invalid" } ]
You can deserialize and ignore errors like this:
var products = JsonConvert.DeserializeObject<List<Product>>(productsJson, new JsonSerializerSettings() { Error = (sender, error) => error.ErrorContext.Handled = true }); foreach (var product in products ?? Enumerable.Empty<Product>()) { Console.WriteLine($"{product.ProductName}: {product.Price}"); }
This will output:
Laptop: 1200.5
The second product (Phone
) had a deserialization error and was excluded. Only the valid objects are included in the result.
Example - Malformed JSON Returning Null
If the JSON is malformed, such as containing a stray character like a #
, deserialization might return null
:
[ { # "Id": 1, "Project": { "Id": 1, "Name": "Project Z" } } ]
Now, when deserializing with error handling:
var employees = JsonConvert.DeserializeObject<List<Employee>>(employeeJson, new JsonSerializerSettings() { Error = (sender, error) => error.ErrorContext.Handled = true }); Console.WriteLine($"Employees is null? {employees is null}");
This will output:
Employees is null? True
In this case, the malformed JSON caused deserialization to fail, resulting in null
. Always remember to null-check the results.
Reporting Errors
Besides ignoring errors, you can also use the error handler to log or report errors. For instance, you can collect error messages and display them to the user:
[ { "Id": 1, "Project": { "Id": null, "Name": "Project A" } }, { "Id": "invalid", "Project": { "Id": 2, "Name": "Project B" } } ]
You can capture errors like this:
var errorMessages = new List<string>(); var employees = JsonConvert.DeserializeObject<List<Employee>>(employeeJson, new JsonSerializerSettings() { Error = (sender, error) => { errorMessages.Add(error.ErrorContext.Error.Message); error.ErrorContext.Handled = true; } }); foreach (var message in errorMessages) { Console.WriteLine(message); Console.WriteLine(); }
This will output:
Error converting value {null} to type 'System.Int32'. Path '[0].Project.Id', line 4, position 26. Could not convert string to integer: invalid. Path '[1].Id', line 7, position 20.
By capturing and reporting these errors, you can provide better feedback to the user or log them for further investigation.
- How to batch read with Threading.ChannelReader in C#
- JsonException: A possible object cycle was detected
- JSON value could not be converted to System.String in C#
- Calling ‘BuildServiceProvider’ from application code results in an additional copy of singleton services being created
- How to use Newtonsoft in ASP.NET Core
- How to use Polly In C#
- Global exception event handlers in C#
- How to Add or overwrite a value in ConcurrentDictionary in C#