Keywords: C# | JSON Serialization | System.Text.Json | Performance Optimization | .NET Development
Abstract: This article provides an in-depth exploration of various methods for serializing lists to JSON in C#, focusing on the usage of two mainstream libraries: System.Text.Json and Newtonsoft.Json. It details the evolution from early JavaScriptSerializer to modern System.Text.Json source generation, demonstrates best practices across different .NET versions through code examples, and offers performance comparisons and memory allocation analysis to help developers choose the most suitable serialization approach for specific scenarios.
Introduction
In modern software development, JSON (JavaScript Object Notation) has become the de facto standard for data exchange. Particularly in web applications and API development, serializing C# object lists to JSON strings is a common requirement. Based on practical development scenarios, this article systematically introduces various methods for list serialization in C#, with a focus on analyzing the advantages, disadvantages, and applicable scenarios of each approach.
Problem Context and Risks of Manual Serialization
In actual development, developers sometimes use manual string concatenation to implement JSON serialization, as shown in the following example:
StringBuilder TheListBuilder = new StringBuilder();
TheListBuilder.Append("[");
int TheCounter = 0;
foreach (MyObjectInJson TheObject in TheList)
{
TheCounter++;
TheListBuilder.Append(TheObject.ObjectInJson);
if (TheCounter != TheList.Count())
{
TheListBuilder.Append(",");
}
}
TheListBuilder.Append("]");
return TheListBuilder.ToString();While this method is intuitive, it carries significant risks: it's prone to format errors resulting in invalid JSON, difficult to handle special character escaping, hard to maintain, and performs poorly. More importantly, when the ObjectInJson property itself is already serialized JSON, this double serialization can lead to data format confusion.
Modern Solutions for .NET 6.0 and Later
For applications using .NET 6.0 or newer versions, it's recommended to use the source generation feature of the System.Text.Json library. This method generates serialization code at compile time, avoiding reflection overhead at runtime and significantly improving performance.
First, define the data model:
public record MyObjectInJson(
long ObjectId,
string ObjectInJson
);Create the serialization context:
[JsonSerializable(typeof(List<MyObjectInJson>))]
internal partial class Context : JsonSerializerContext
{
}Perform the serialization operation:
using System.Text.Json;
using System.Text.Json.Serialization;
var aList = new List<MyObjectInJson>
{
new(1, "1"),
new(2, "2")
};
var json = JsonSerializer.Serialize(aList, Context.Default.ListMyObjectInJson);The source generation mode optimizes performance through compile-time code generation, but be aware of its design limitations. If the data model cannot meet these limitations, the traditional reflection-based method remains available:
var json = JsonSerializer.Serialize(aList);Formatting Options and Custom Configuration
In practical applications, it's often necessary to format JSON output to meet specific requirements. System.Text.Json provides rich configuration options:
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
var json = JsonSerializer.Serialize(aList, options);Using PropertyNamingPolicy.CamelCase converts property names to camelCase, WriteIndented=true enables formatted output, and DefaultIgnoreCondition controls the serialization behavior of null values.
Compatibility Solutions for Earlier .NET Versions
.NET Core 3.0 to 5.0 Versions
For projects using .NET Core 3.0 to 5.0, while System.Text.Json is available, it's recommended to upgrade to newer .NET versions for better performance and feature support. The basic usage is as follows:
using System.Text.Json;
var json = JsonSerializer.Serialize(aList);.NET Core 2.2 and Earlier Versions
For legacy systems or projects that cannot be upgraded, Newtonsoft.Json (Json.NET) is the recommended choice. First, install the package via NuGet:
PM> Install-Package Newtonsoft.JsonThen use JsonConvert for serialization:
using Newtonsoft.Json;
var json = JsonConvert.SerializeObject(aList);Newtonsoft.Json also supports rich configuration options:
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
};
var json = JsonConvert.SerializeObject(aList, settings);Performance Analysis and Best Practices
Comparing the performance of different serialization methods through benchmark tests:
- System.Text.Json Source Generation: Optimal performance, least memory allocation, suitable for high-performance scenarios
- System.Text.Json Reflection Mode: Good performance, strong compatibility
- Newtonsoft.Json: Feature-rich, but relatively lower performance
- JavaScriptSerializer: Obsolete, not recommended for new projects
In actual projects, it's recommended to:
- Prioritize using System.Text.Json source generation mode
- Consider Newtonsoft.Json for complex serialization requirements
- Avoid manual JSON string concatenation
- Choose appropriate serialization options based on data volume
Handling Special Scenarios
When dealing with objects containing pre-serialized JSON properties, special attention is needed to avoid double serialization. The correct approach is to ensure that the ObjectInJson property stores raw data rather than serialized strings, or use custom converters to handle such special cases.
Conclusion
JSON serialization technology in C# has evolved from early JavaScriptSerializer to modern System.Text.Json. Developers should choose the appropriate serialization solution based on project requirements, target framework, and performance needs. For new projects, strongly recommend using System.Text.Json's source generation feature, which provides excellent performance while maintaining code simplicity and maintainability.