C# Object serialization安全最优方法及自定义ArrayList序列化实现咨询
Great question! When working on custom ArrayList serialization in C#, it's crucial to prioritize security while following best practices that align with your use case—whether you need cross-platform compatibility, performance, or strict data protection. Let's walk through the safest and most optimal approaches, with actionable code examples tailored to your scenario:
This is the modern, secure default choice for most C# serialization tasks. It’s fast, has built-in security guards, and offers flexible configuration.
Key Security & Best Practice Notes:
- By default, it only serializes public properties, avoiding accidental exposure of sensitive non-public data.
- It blocks unsafe type deserialization by default, preventing type confusion attacks.
- You can fine-tune behavior via
JsonSerializerOptions(e.g., ignore null values, rename properties).
Custom ArrayList Implementation Example:
using System.Collections; using System.Text.Json; using System.Text.Json.Serialization; // Your custom ArrayList with extra metadata public class CustomArrayList : ArrayList { [JsonPropertyName("custom_metadata")] // Explicit naming for clarity public string CustomMetadata { get; set; } = "MyCustomList"; } public class JsonSerializationDemo { public static void SerializeAndDeserialize() { var customList = new CustomArrayList { "First Item", 42, new { Product = "Laptop" }, CustomMetadata = "UpdatedListMetadata" }; // Configure options for readability and proper serialization var options = new JsonSerializerOptions { WriteIndented = true, Converters = { new JsonStringEnumConverter() } }; // Serialize to JSON string string jsonOutput = JsonSerializer.Serialize(customList, options); Console.WriteLine("Serialized JSON:\n" + jsonOutput); // Deserialize back to CustomArrayList var deserializedList = JsonSerializer.Deserialize<CustomArrayList>(jsonOutput, options); Console.WriteLine($"\nDeserialized Metadata: {deserializedList.CustomMetadata}"); Console.WriteLine($"First Element: {deserializedList[0]}"); } }
If you need XML-based serialization (e.g., for legacy systems or standardized data formats), XmlSerializer is a secure, well-supported option.
Key Security & Best Practice Notes:
- Uses
XmlIgnoreto exclude sensitive properties from serialization. - Supports XML schema validation to block malicious or malformed input.
- Requires a parameterless constructor (which
ArrayListalready provides).
Custom ArrayList Implementation Example:
using System.Collections; using System.Xml.Serialization; using System.IO; public class CustomArrayList : ArrayList { [XmlElement("CustomMetadata")] // Explicit XML element name public string CustomMetadata { get; set; } = "XmlCustomList"; } public class XmlSerializationDemo { public static void SerializeAndDeserialize() { var customList = new CustomArrayList { "Book", 99.99, CustomMetadata = "XmlListMetadata" }; var serializer = new XmlSerializer(typeof(CustomArrayList)); // Serialize to XML file using (var writer = new StreamWriter("custom_list.xml")) { serializer.Serialize(writer, customList); } // Deserialize from XML file using (var reader = new StreamReader("custom_list.xml")) { var deserializedList = (CustomArrayList)serializer.Deserialize(reader); Console.WriteLine($"Deserialized Metadata: {deserializedList.CustomMetadata}"); Console.WriteLine($"Second Element: {deserializedList[1]}"); } } }
Important: Microsoft has marked BinaryFormatter as obsolete because it enables remote code execution attacks if used to deserialize untrusted data. Only use this in fully controlled, trusted environments (e.g., local file serialization with no external input).
If You Must Use It:
- Restrict deserializable types with a
SerializationBinderto block unexpected types. - Encrypt the serialized byte stream to prevent tampering.
Example with Security Safeguards:
using System.Collections; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; [Serializable] // Required for BinaryFormatter public class CustomArrayList : ArrayList { public string CustomMetadata { get; set; } = "BinaryCustomList"; } public class BinarySerializationDemo { public static void SerializeAndDeserialize() { var customList = new CustomArrayList { "Phone", 699, CustomMetadata = "BinaryListMetadata" }; var formatter = new BinaryFormatter(); // Restrict allowed types to prevent malicious deserialization formatter.Binder = new CustomSerializationBinder(); // Serialize to binary file using (var stream = new FileStream("custom_list.bin", FileMode.Create)) { formatter.Serialize(stream, customList); } // Deserialize from binary file using (var stream = new FileStream("custom_list.bin", FileMode.Open)) { var deserializedList = (CustomArrayList)formatter.Deserialize(stream); Console.WriteLine($"Deserialized Metadata: {deserializedList.CustomMetadata}"); } } } // Custom binder to allow only trusted types public class CustomSerializationBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { if (typeName == typeof(CustomArrayList).FullName) return typeof(CustomArrayList); if (typeName == typeof(string).FullName || typeName == typeof(int).FullName) return Type.GetType($"{typeName}, {assemblyName}"); throw new SerializationException($"Type {typeName} is not allowed for deserialization."); } }
- Minimize Data Exposure: Only serialize necessary data. Use
JsonIgnore,XmlIgnore, orNonSerializedto exclude sensitive fields. - Validate Input: Before deserializing, verify data integrity (e.g., use hash signatures) and ensure it comes from a trusted source.
- Prefer Generic Collections: Whenever possible, replace
ArrayListwithList<T>—it’s type-safe, faster, and reduces serialization ambiguity. - Encrypt Sensitive Data: If you must serialize sensitive information, encrypt the final serialized output (e.g., using AES).
- Keep Libraries Updated: Always use the latest versions of serialization libraries to patch known security vulnerabilities.
- If your custom logic is minimal, consider wrapping a
List<T>in a custom class instead of extendingArrayList—this simplifies serialization and improves type safety. - Test end-to-end serialization/deserialization to ensure both custom properties and collection elements are preserved correctly.
内容的提问来源于stack exchange,提问作者Mudassir Ahmed

