Büyük JSON dokümanlarının tamamını deserialize etmeden yalnızca ihtiyaç duyduğun alanları okuyan,
streaming, chunk-safe ve sıfır üçüncü parti bağımlılığa sahip hafif bir .NET okuma katmanı.
Temelde Utf8JsonReader çalışır.
Elinde metadata, orders,
logs, attachments gibi
alanlar barındıran büyük bir JSON varsa ve uygulamanın tek ihtiyacı customer
alanıysa, geri kalan milyonlarca byte'ı parse edip bellekte tutmaya gerek yok.
| Özellik | Geleneksel Deserialize | JsonSafeReader |
|---|---|---|
| Tüm JSON'u parse etme | Genellikle | Gerekmeyebilir |
| Target property erişimi | Sonradan erişim | Doğrudan aranabilir |
| Stream desteği | Senaryoya bağlı | ✅ |
| Chunk parsing | ✕ | ✅ |
JsonReaderState devamlılığı | ✕ | ✅ |
ArrayPool kullanımı | Genellikle yok | ✅ |
| Property skip | Sınırlı | ✅ |
Doğrudan Deserialize<T> | — | ✅ |
| max buffer limiti | Genellikle yok | ✅ |
| Invalid UTF-8 telemetry | Genellikle yok | ✅ |
| Üçüncü parti bağımlılık | — | ✕ Yok |
Yalnızca belirlediğin property'leri okur, geri kalanını reader.Skip() ile geçer.
4096 byte'lık parçalar halinde okur; tüm stream'i tek seferde belleğe almaz.
Bir token chunk sınırında bölünse bile parser state kaybolmaz, güvenle devam eder.
Streaming API'lerinde buffer'lar pool'dan kiralanır, iş bitince iade edilir.
1024 byte'a kadar küçük içerikler için stackalloc kullanılır, heap baskısı azalır.
Varsayılan 16 MB sınırı; aşırı büyük bir token sınırsız buffer büyümesine yol açamaz.
Bozuk byte dizileri U+FFFD ile değiştirilir, uygulama çökmez.
Kaç geçersiz sequence tespit edildiği sayılır ve Trace.TraceWarning ile bildirilir.
EF BB BF ile başlayan içerikler otomatik tespit edilip temizlenir.
CommentHandling.Skip sayesinde yorum satırı içeren JSON'lar da tolere edilir.
AllowTrailingCommas hem streaming hem non-streaming yolda tutarlı çalışır.
customer, Customer, CUSTOMER aynı hedef sayılır.
Kütüphane kendi JSON parser'ını icat etmez; hız ve Span<byte> desteği için
doğrudan Utf8JsonReader'a dayanır. Namespace: DSO.Core.JsonSafeReader,
ana sınıf: JsonSafeReader.
┌─────────────────────┐ │ JsonSafeReader │ └──────────┬──────────┘ │ ┌────────────────┼────────────────┐ │ │ │ ▼ ▼ ▼ String Input Byte Input Stream Input │ │ │ └────────────────┼────────────────┘ ▼ Utf8JsonReader │ ┌──────────┴──────────┐ │ │ ▼ ▼ Property Filter Exclude Filter │ │ └──────────┬──────────┘ ▼ Target JSON Element │ ┌──────────┴──────────┐ │ │ ▼ ▼ JsonDocument Direct Deserialize<T>
100 MB — 1 GB+ boyutundaki kaynaklarda yalnızca gereken alanların okunması.
Devasa bir REST response'undan tek bir property'nin çıkarılması.
Büyük JSON log dosyalarından yalnızca ilgili alanların ayıklanması.
JSON'un belirli bölümlerinin başka sistemlere aktarılması.
Uzun süre çalışan servislerde allocation ve memory pressure'ın azaltılması.
appsettings.json ya da özel config dosyalarının section bazlı okunması.
Stream olarak gelen JSON'un tamamını belleğe almadan işlenmesi.
Çok sayıda JSON request'inin düşük GC baskısıyla karşılanması.
Kaynak kodu projene dahil et: using DSO.Core.JsonSafeReader;
string json = """ { "customer": { "Id": 101, "Name": "Ayşe Yılmaz" }, "order": { "OrderId": 5001, "Total": 199.90 } } """; JsonElement? customer = JsonSafeReader.ReadJsonFromString( json, new[] { "customer" });
public class Customer { public int Id { get; set; } public string Name { get; set; } = string.Empty; } Customer? customer = JsonSafeReader.DeserializeFromString<Customer>( json, new[] { "customer" }); // JSON → JsonDocument → JsonElement → GetRawText() → Deserialize // zincirini atlar; doğrudan JsonSerializer.Deserialize(ref reader, options) kullanır.
byte[] jsonBytes = Encoding.UTF8.GetBytes(json); JsonElement? customer = JsonSafeReader.ReadJsonFromBytes( jsonBytes, new[] { "customer" });
await using FileStream stream = File.OpenRead("large-data.json"); Customer? customer = await JsonSafeReader.DeserializeFromStreamAsync<Customer>( stream, new[] { "customer" }); // büyük token'lar için opsiyonel limit: // maxBufferSize: 8 * 1024 * 1024
JsonElement? result = JsonSafeReader.ReadJsonFromString( json, Array.Empty<string>(), "logs", "attachments", "audit"); // belirtilen property'ler reader.Skip() ile geçilir, // büyük alt ağaçlar application seviyesinde hiç oluşmaz.
JsonElement settings = JsonSafeReader.GetAppSetting(); JsonElement? database = JsonSafeReader.ReadSectionFromAppSetting("Database"); // async ve dosya adı belirtilen varyantlar da mevcuttur: // GetAppSettingWithFileNameAsync("production")
Girdi, birden fazla katmandan geçerek işlenir — her katman bir sınıf hatasını önceden kapatır.
Input │ ├── Null / Empty validation │ ├── BOM handling │ ├── UTF-8 fallback → U+FFFD + Trace warning │ ├── Invalid UTF-8 tracking │ ├── JSON structural validation │ ├── Chunk state preservation → JsonReaderState + BytesConsumed │ ├── Buffer limit → maxBufferSize (default 16 MB) │ └── Meaningful exceptions → FileNotFoundException / ArgumentException / JsonException
ReadJsonFromString(string jsonString, string[] targetElements, params string[] excludeElementNames) ReadJsonFromBytes(ReadOnlySpan<byte> jsonBytes, string[] targetElements, params string[] excludeElementNames) ReadJsonFromStreamAsync(Stream stream, string[] targetElements, string[]? excludeElementNames = null, int maxBufferSize = ...)
DeserializeFromString<T>(string jsonString, string[] targetElements, string[]? excludeElementNames = null, JsonSerializerOptions? options = null) DeserializeFromBytes<T>(byte[] jsonBytes, string[] targetElements, string[]? excludeElementNames = null, JsonSerializerOptions? options = null) DeserializeFromStreamAsync<T>(Stream stream, string[] targetElements, string[]? excludeElementNames = null, JsonSerializerOptions? options = null, int maxBufferSize = ...)
ReadSectionAsElement(string jsonString, string targetPropertyName) ReadSectionAsElementFromFilePath(string filePath, string targetPropertyName) ReadSectionAsElementFromFilePathAsync(string filePath, string targetPropertyName, int maxBufferSize = ...)
GetAppSetting() GetAppSettingAsync() GetAppSetting(string filePath) GetAppSettingAsync(string filePath) GetAppSettingAsync(byte[] jsonBytes) GetAppSettingWithFileNameAsync(string fileName) ReadSectionFromAppSetting(string name) ReadSectionFromAppSettingAsync(string name)
GetProjectSetting() GetProjectSettingAsync() ReadSectionFromProjectSetting(string name) ReadSectionFromProjectSettingAsync(string name)
Harici bir JSON parser ya da üçüncü parti framework gerekmez — tüm işleme System.Text.Json
üzerinden yapılır. Kaynak kodunu projene dahil et:
using DSO.Core.JsonSafeReader; JsonElement? result = JsonSafeReader.ReadJsonFromString( json, new[] { "customer" });