Trong bai viet nay, chung ta se tim hieu ngan gon ve dinh dang Concise Binary Object Representation (CBOR), khi nao va vi sao nen su dung no, cung nhu cach lam viec voi goi System.Formats.Cbor trong .NET.
Mục lục
Bo canh: serialize du lieu va JSON
CBOR la mot dinh dang serialize du lieu. No nhan du lieu co cau truc va mo ta chuoi byte dai dien cho du lieu do. Chuoi byte nay co the duoc gui qua mang hoac luu vao tep, sau do duoc deserialize de khoi phuc bieu dien cua du lieu ban dau.
Mot trong nhung dinh dang pho bien nhat hien nay la JavaScript Object Notation (JSON). Vi du:
{
"name": "Goose",
"breed": "Labrador",
"age": 8,
"toys": ["ducky", "flamingo", "ice-cream"],
"owner": {
"name": "Sock"
}
}
JSON co mot so dac diem dang gia:
- JSON gan nhu la van ban thuan tuy, thuong duoc ma hoa bang UTF-8, nen con nguoi co the doc duoc. Dieu nay giup viec go loi cac yeu cau mang don gian hon.
- JSON co schema tu mo ta. Ta co the viet bo giai ma tong quat ma khong can biet truoc rang truong thu ba la
age.
Kha nang go loi cua dinh dang van ban rat huu ich, nhung JSON co the kem hieu qua neu du lieu truyen di khong phai la van ban. Vi du, mot gia tri boolean trong JSON duoc ma hoa thanh true hoac false, chiem 4 hoac 5 byte de bieu dien mot bit du lieu 0 hoac 1. Viec giai ma cung ton nhieu chi phi hon so voi mot dinh dang nhi phan don gian.
Ngoai ra, JSON khong co kieu nhi phan. Neu muon gui du lieu nhi phan nguyen ban, ta thuong phai ma hoa no thanh chuoi Base64. Cach nay lam kich thuoc du lieu tang khoang 33%, vi Base64 bien moi 3 byte du lieu nhi phan thanh 4 byte hoac ky tu. Bo sung vao do la phan phuc tap o ben giai ma.
CBOR duoc tao ra de giai quyet truc tiep ca hai han che nay.
CBOR la gi?
Compact Binary Object Representation, viet tat la CBOR, la mot tieu chuan IETF voi cac muc tieu chinh:
- Ma hoa duoc cac kieu du lieu giong JSON va ho tro tu nhien cho du lieu nhi phan.
- Giup ma encoder va decoder don gian nhat co the.
- Tao ra payload nho hon JSON.
- Tu mo ta, tuong tu JSON, XML va MessagePack, khac voi Protobuf.
CBOR ban dau huong toi cac kich ban Internet van vat, noi tai nguyen bi han che nhung can gui va xu ly nhieu du lieu. Tuy nhien, cac dac diem cua CBOR cung huu ich trong nhieu truong hop khac.
Vi CBOR co the bieu dien tat ca cac kieu du lieu cua JSON va mot so kieu bo sung, cau truc JSON o tren co the duoc ma hoa thanh:
A5646E616D6565476F6F7365656272656564684C61627261646F720A
Trong thuc te, day la dang duoc truyen hoac luu tru. No khong de doc, vi vay CBOR cung co Concise Diagnostic Notation, co hinh thuc gan giong JSON. Ta cung thuong thay dang hex kem chu thich:
A5 # map(5)
64 # text(4)
6E616D65 # "name"
65 # text(5)
476F6F7365 # "Goose"
65 # text(5)
6272656564 # "breed"
68 # text(8)
4C61627261646F72 # "Labrador"
63 # text(3)
616765 # "age"
08 # unsigned(8)
64 # text(4)
746F7973 # "toys"
83 # array(3)
65 # text(5)
6475636B79 # "ducky"
68 # text(8)
666C616D696E676F # "flamingo"
69 # text(9)
6963652D637265616D # "ice-cream"
65 # text(5)
6F776E6572 # "owner"
A1 # map(1)
64 # text(4)
6E616D65 # "name"
64 # text(4)
536F636B # "Sock"
Moi phan tu trong tai lieu CBOR gom mot byte header va co the co them phan than gom nhieu byte. Header mo ta kieu du lieu; voi cac kieu don gian, no co the chua ca gia tri, chang han so nguyen khong dau nho 08. Map va array chua kich thuoc ngay trong header, sau do moi phan tu lai co mot header rieng.
CBOR cung ho tro chuoi, map va array co do dai khong xac dinh. Tinh nang nay phu hop voi cac kich ban streaming, khi chua biet truoc kich thuoc du lieu.
Kich thuoc payload CBOR so voi JSON phu thuoc nhieu vao du lieu. So nho, boolean va du lieu nhi phan thuong tiet kiem hon voi CBOR. Do dai van ban thi gan tuong duong vi ca hai deu dung UTF-8.
Mot uu diem cua CBOR voi van ban la kich thuoc van ban duoc ghi truoc theo so byte. Decoder co the dung thong tin nay de cap phat truoc buffer co kich thuoc phu hop. Ngoai ra, van ban UTF-8 trong CBOR khong can cac chuoi escape, vi decoder da biet so byte cua truong.
CBOR so voi Protobuf va MessagePack
Protocol Buffers (Protobuf) do Google phat trien va la dinh dang trao doi chinh cua gRPC. Day cung la giao thuc nhi phan, nhung khac JSON va CBOR, Protobuf phu thuoc vao cac tep schema .proto duoc chia se truoc. Nho schema, Protobuf co the dat hieu nang cao va tao payload rat nho.
Su phu thuoc vao schema vua la uu diem vua la han che. Schema cho phep toi uu encoder va dinh dang, nhung doi hoi ben san xuat va ben tieu thu phai thong nhat va quan ly chung mot schema. Dieu nay phu hop voi moi truong duoc kiem soat, nhung kem linh hoat hon CBOR, von tu mo ta.
CBOR la tieu chuan IETF, trong khi Protobuf chu yeu dua tren mot chuan thuc te.
MessagePack giai quyet nhieu bai toan giong CBOR: mot dinh dang nhi phan nhanh, thay the JSON, ho tro cac kieu tuong tu JSON va ca du lieu nhi phan. Khac biet lon la MessagePack khong co mot tieu chuan chinh thuc nhu CBOR.
Ngoai van de tieu chuan hoa, mot diem khac dang chu y la CBOR ho tro streaming. Co the xem CBOR nhu mot phien ban duoc tieu chuan hoa chinh thuc cua cach tiep can gan voi MessagePack.
Su dung CBOR trong .NET 10
Tu .NET 10, phat hanh vao thang 11 nam 2025, .NET co ho tro chinh thuc cho viec ma hoa va giai ma CBOR thong qua goi NuGet System.Formats.Cbor. G pho nay cung ho tro .NET Framework va .NET Standard 2.0, nen co the dung trong nhieu ung dung .NET.
dotnet add package System.Formats.Cbor
Hai kieu chinh trong goi la:
CborWriter: ghi du lieu vao buffer theo dinh dang CBOR.CborReader: doc du lieu nhi phan CBOR tu mang byte.
Day la cac API muc thap hon nhieu so voi khi lam viec voi JSON thong qua Newtonsoft.Json hay System.Text.Json. System.Formats.Cbor khong tu dong chuyen doi object co kieu manh. Thay vao do, ta doc va ghi cac gia tri nguyen thuy.
Ghi CBOR bang CborWriter
using System.Formats.Cbor;
var writer = new CborWriter();
writer.WriteStartMap(5);
writer.WriteTextString("name");
writer.WriteTextString("Goose");
writer.WriteTextString("breed");
writer.WriteTextString("Labrador");
writer.WriteTextString("age");
writer.WriteUInt32(8);
writer.WriteTextString("toys");
writer.WriteStartArray(3);
writer.WriteTextString("ducky");
writer.WriteTextString("flamingo");
writer.WriteTextString("ice-cream");
writer.WriteEndArray();
writer.WriteTextString("owner");
writer.WriteStartMap(1);
writer.WriteTextString("name");
writer.WriteTextString("Sock");
writer.WriteEndMap();
writer.WriteEndMap();
Span<byte> encodedBytes = stackalloc byte[512];
int bytesWritten = writer.Encode(encodedBytes);
encodedBytes = encodedBytes[..bytesWritten];
Console.WriteLine($"Hex representation: {Convert.ToHexString(encodedBytes)}");
Mot so diem can luu y:
- Neu biet truoc kich thuoc array hoac map, nen truyen kich thuoc ngay tu dau. Neu khong, collection se duoc tao voi do dai khong xac dinh.
- Key cua map co the la bat ky kieu nao, khong nhat thiet phai la chuoi.
- Khi ghi,
CborWriterluu du lieu trong buffer noi bo. Gia tri hoan chinh duoc lay bangEncode()hoacTryEncode(). CborWriternem exception neu ta tao tai lieu khong hop le, chang han ket thuc map khi khong co map dang mo, hoac goiEncode()khi tai lieu con dang do.
Ket qua la dang hex tuong ung voi du lieu o tren:
Hex representation: A5646E616D6565476F6F7365656272656564684C61627261646F72
CborWriter nhan CborWriterOptions de dieu khien cach hoat dong:
public sealed class CborWriterOptions
{
public CborConformanceMode ConformanceMode { get; set; }
public bool ConvertIndefiniteLengthEncodings { get; set; }
public bool AllowMultipleRootLevelValues { get; set; }
public int MaxDepth { get; set; }
public int InitialCapacity { get; set; }
}
Thuoc tinh dang chu y nhat la ConformanceMode. Cac gia tri co ban gom:
Lax: dam bao du lieu CBOR co cau truc hop le theo RFC 7049.Strict: mo rong che do Lax, khong cho phep key trung trong map, yeu cau gia tri don gian duoc ma hoa ngan gon va chuoi UTF-8 hop le.Canonical: mo rong Strict, yeu cau so nguyen duoc ma hoa ngan nhat, key trong map duoc sap xep theo dang ma hoa va cac item do dai khong xac dinh duoc chuyen thanh do dai xac dinh.Ctap2Canonical: che do canonical theo tieu chuan CTAP 2.0, khong cho phep tag CBOR va khong thay doi bieu dien cua gia tri so thuc.
Vi du:
var writer = new CborWriter(CborConformanceMode.Canonical);
Trong che do nay, cac thuoc tinh duoc sap xep. Vi du, key age co the duoc ma hoa truoc tien. Cach lam nay co the giup decoder xu ly de hon neu ta biet chac dang du lieu mong doi.
Doc CBOR bang CborReader
Sau khi co du lieu CBOR da ma hoa, ta co the dung CborReader de giai ma ve cac kieu .NET. Vi day la API muc thap, co nhieu cach viet decoder tuy theo muc do kiem soat du lieu, yeu cau hieu nang va muc dich xu ly.
var reader = new CborReader(encodedBytes.ToArray());
var mapCount = reader.ReadStartMap();
Span<char> buffer = stackalloc char[10];
for (var i = 0; i < mapCount; i++)
{
if (!reader.TryReadTextString(buffer, out var length))
{
throw new Exception("Buffer too small");
}
var key = buffer[..length];
switch (key)
{
case "age":
Console.WriteLine($"age: {reader.ReadInt32()}");
break;
case "name":
Console.WriteLine($"name: {reader.ReadTextString()}");
break;
case "breed":
Console.WriteLine($"breed: {reader.ReadTextString()}");
break;
case "toys":
Console.WriteLine("toys: ");
var arrayCount = reader.ReadStartArray();
for (int item = 0; item < arrayCount; item++)
{
Console.WriteLine($"- {reader.ReadTextString()}");
}
reader.ReadEndArray();
break;
case "owner":
Console.WriteLine("owner: ");
var innerMapCount = reader.ReadStartMap();
for (int item = 0; item < innerMapCount; item++)
{
Console.WriteLine($" {reader.ReadTextString()}: {reader.ReadTextString()}");
}
reader.ReadEndMap();
break;
default:
Console.WriteLine($"Unknown key '{key}': {Convert.ToHexString(reader.ReadEncodedValue().Span)}");
break;
}
}
reader.ReadEndMap();
So voi JsonConvert.DeserializeObject<T>, cach nay dai hon dang ke. Tuy nhien, day la chu y cua API muc thap. Ta co the xay dung API tong quat hon tren CborReader, nhung can than trong khi deserialize du lieu khong ro rang.
Neu biet truoc dang du lieu va cac gia tri hop le, cach doc tung truong nhu tren thuong cho hieu nang rat tot. Ket qua in ra co the la:
name: Goose
breed: Labrador
age: 8
toys:
- ducky
- flamingo
- ice-cream
owner:
name: Sock
Vi du tren cung xu ly kha nang tuong thich tien: decoder cu co the gap truong moi ma no khong biet. Neu bo phan xu ly toys, ket qua co the la:
name: Goose
breed: Labrador
age: 8
Unknown key 'toys': 83656475636B7968666C616D696E676F696963652D637265616D
owner:
name: Sock
Decoder van co the di den truong tiep theo trong map va tiep tuc xu ly. ReadEncodedValue() doc toan bo gia tri tiep theo va bo qua no, vi vay ung dung tu quyet dinh cach xu ly gia tri khong biet.
Neu can decoder that su tong quat, co the dung:
CborReaderState state = reader.PeekState();
PeekState() xem token CBOR tiep theo ma khong bo qua no. CborReaderState la mot enum mo ta cac kieu gia tri co the gap, tu do ta chon phuong thuc doc phu hop nhu ReadTextString() hoac ReadInt32().
Co nen su dung CBOR?
Cau tra loi quen thuoc la: tuy truong hop. CBOR la mot phien ban gon hon cua JSON, dac biet huu ich khi can ma hoa du lieu nhi phan hoac streaming. Tuy nhien, voi phan lon API thong thuong, JSON van dap ung tot va de su dung hon.
Mot truong hop dang chu y la ASP.NET Core, trong phan ho tro Device Bound Session Credentials (DBSC) duoc gioi thieu trong .NET 11. Trong do, CborWriter va CborReader duoc dung lam dinh dang nhi phan don gian. Du lieu sau do duoc ma hoa bang Data Protection, ma hoa Base64 URL va dat vao cookie:
public string GenerateRefreshChallenge(
ClaimsPrincipal principal,
string sessionId,
TimeSpan lifetime)
{
var claimUid = ComputeClaimUid(principal);
var writer = new CborWriter(allowMultipleRootLevelValues: true);
writer.WriteTextString(claimUid);
writer.WriteTextString(sessionId);
return WebEncoders.Base64UrlEncode(
_refreshProtector.Protect(writer.Encode(), lifetime));
}
Diem thu vi la doan ma nay khong co gang mo phong JSON. Thay vi tao mot map gom cac cap key-value, CborWriter ghi hai gia tri van ban o cap goc. Ket qua gan nhu la dang nhi phan cua <claimUid><sessionId>.
Vi du lieu chi duoc cung mot ung dung dang chay doc, cach ma hoa ngan gon nay la hop ly. Day cung la goi y quan trong ve khi nao nen can nhac CBOR: khi can mot dinh dang nhi phan nho, nhanh, chi duoc doc boi cac thanh phan da biet truoc cau truc du lieu.
Tom tat
CBOR la dinh dang serialize nhi phan co the ma hoa cac kieu du lieu giong JSON va bo sung ho tro cho du lieu nhi phan. So voi JSON, CBOR co the tao message nho hon, xu ly hieu qua hon voi so, boolean va du lieu nhi phan, dong thoi ho tro streaming.
So voi Protobuf, CBOR tu mo ta va khong yeu cau schema chia se truoc. So voi MessagePack, CBOR co uu diem la mot tieu chuan IETF chinh thuc va ho tro cac kich ban streaming.
Trong .NET, goi System.Formats.Cbor cung cap hai API muc thap la CborWriter va CborReader. Chung cho phep ghi va doc gia tri CBOR nguyen thuy, nhung khong tu dong serialize hoac deserialize object theo kieu manh. Vi vay, CBOR phu hop nhat khi ta can kiem soat chat cach ma hoa, toi uu kich thuoc hoac xay dung giao thuc nhi phan rieng.



