Khái niệm
- Binary Serialization: Chuyển đổi object thành định dạng nhị phân (không đọc được bằng mắt thường).
- Deserialization: Chuyển đổi ngược từ nhị phân về object gốc.
Đặc điểm Binary Serialization
| Đặc điểm | Mô tả |
| Định dạng | Nhị phân (binary), compact, nhanh |
| Đọc được bởi người | Không |
| Kích thước | Nhỏ hơn XML/JSON |
| Hiệu năng | Rất nhanh |
| Type fidelity | Giữ toàn bộ type info (private fields, assembly version) |
| Bảo mật | Không an toàn cho untrusted data (có thể execute code) |
Thư viện sử dụng
⚠️ Lưu ý quan trọng: BinaryFormatter đã bị deprecated ( obsoleted ) từ .NET 5+ và bị loại bỏ hoàn toàn từ .NET 8+ do lỗ hổng bảo mật nghiêm trọng (CVE-2023-XXXX).
Cách cũ (Legacy - .NET Framework / .NET Core 3.1)
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
[Serializable]
public class Demo
{
public string ApplicationName { get; set; } = "Binary Serialize";
public int ApplicationId { get; set; } = 1001;
}
class Program
{
static void Main()
{
var sample = new Demo();
// Serialize
using (var fileStream = new FileStream(@"C:\Temp\Questions.dat", FileMode.Create))
{
var formatter = new BinaryFormatter();
formatter.Serialize(fileStream, sample);
}
// Deserialize
using (var fileStream = new FileStream(@"C:\Temp\Questions.dat", FileMode.Open))
{
var formatter = new BinaryFormatter();
var deserialized = (Demo)formatter.Deserialize(fileStream);
Console.WriteLine($"Name: {deserialized.ApplicationName}, Id: {deserialized.ApplicationId}");
}
}
}
Thay thế an toàn cho .NET 5+ (Modern Alternatives)
1. System.Text.Json (Khuyến nghị chính thức)
using System.Text.Json;
public class Demo
{
public string ApplicationName { get; set; } = "JSON Serialize";
public int ApplicationId { get; set; } = 1001;
}
class Program
{
static void Main()
{
var sample = new Demo();
// Serialize to bytes (UTF-8)
byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(sample);
File.WriteAllBytes(@"C:\Temp\demo.json", jsonBytes);
// Deserialize from bytes
byte[] readBytes = File.ReadAllBytes(@"C:\Temp\demo.json");
var deserialized = JsonSerializer.Deserialize<Demo>(readBytes);
Console.WriteLine($"Name: {deserialized.ApplicationName}, Id: {deserialized.ApplicationId}");
}
}
2. MessagePack (Hiệu năng cao, binary compact)
// NuGet: MessagePack
using MessagePack;
[MessagePackObject]
public class Demo
{
[Key(0)] public string ApplicationName { get; set; }
[Key(1)] public int ApplicationId { get; set; }
}
class Program
{
static void Main()
{
var sample = new Demo { ApplicationName = "MsgPack", ApplicationId = 2001 };
// Serialize
byte[] bytes = MessagePackSerializer.Serialize(sample);
File.WriteAllBytes(@"C:\Temp\demo.msgpack", bytes);
// Deserialize
var deserialized = MessagePackSerializer.Deserialize<Demo>(File.ReadAllBytes(@"C:\Temp\demo.msgpack"));
}
}
3. Protobuf (Google Protocol Buffers)
// NuGet: Google.Protobuf
// Cần file .proto định nghĩa schema
syntax = "proto3";
message Demo {
string application_name = 1;
int32 application_id = 2;
}
So sánh các phương án hiện đại
| Phương án | Định dạng | Hiệu năng | Kích thước | Cross-platform | Schema |
| System.Text.Json | Text (UTF-8) | Cao | Trung bình | ✅ | Không cần |
| MessagePack | Binary | Rất cao | Nhỏ | ✅ | Attribute/Code-first |
| Protobuf | Binary | Rất cao | Rất nhỏ | ✅ | File .proto (Schema-first) |
| BinaryFormatter | Binary | Trung bình | Trung bình | ❌ (.NET only) | Không cần |
Best Practices
- Không dùng BinaryFormatter cho dữ liệu không tin cậy (untrusted input).
- Dùng System.Text.Json cho hầu hết trường hợp (web API, config, cache).
- Dùng MessagePack/Protobuf cho high-performance, inter-service communication, gRPC.
- Luôn versioning data: thêm
[JsonPropertyName], [Key], optional fields.
- Cân nhắc
JsonSerializerOptions: PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true (debug).