DevOps

VSTest Newtonsoft.Json Bağımlılığını Bırakıyor: Etkisi Ne?

Açık konuşayım: Newtonsoft.Json’un.NET çevreinden yavaş yavaş çekiliyor olması beni bir yandan sevindiriyor, bir yandan da hafif hüzünlendiriyor. Hüzünlü tarafı şu; James Newton-King’in o kütüphanesi olmasaydı, 2010’ların.NET dünyası bugünkünden baya farklı olurdu. Sevindirici tarafı da net: artık yerine geçen System.Text.Json var, hem de performans tarafında fena değil, hatta çoğu senaryoda açık ara öne çıkıyor, Microsoft da kendi SDK’sındaki eski bağımlılıkları tek tek temizliyor işte.

Kendi deneyimimden konuşuyorum, Geçen hafta bir bankacılık projesinde build pipeline’larına bakarken aklıma takıldı: VSTest hâlâ Newtonsoft.Json taşıyor mu acaba? Evet, taşıyordu — ama.NET 11 Preview 4 ve Visual Studio 18.8 ile bu iş kapanıyor gıbı duruyor. Şimdi detayına girelim; çünkü çoğu projede hiçbir şey ölmüyor, ama bazı kurumsal yapılarda build kırılması diye bir şey var ve insanı hiç ummadığı yerden yakalıyor.

Şimdi gelelim işin can alıcı noktasına.

Neden Şimdi? Güvenlik Tarafındaki Hikâye

NuGet.org’da Newtonsoft.Json’un 13.0.0’dan eski tüm sürümleri artık vulnerable diye işaretli. Yanı siz “ben sadece test koşturuyorum” deseniz bile, dotnet test çalışınca CVE geçmişi olan bir bağımlılık sessizce projeye giriyor. İşin aslı bu kadar basit; test platformunun buna artık ihtiyacı yokken o paketi taşımak biraz tuhaf kalıyor.

İlginç olan şu ki, VSTest yıllardır Newtonsoft.Json’u.NET SDK ve Visual Studio içinde shipped ediyordu. Test sonuçlarını serileştirmek, testhost ile platform arasında mesajlaşmak, TRX raporları üretmek… bunların hepsi JSON üzerinden dönüyor, evet. Ama 2025’e gelince System.Text.Json bu yükü gayet taşıyor; hatta.NET Framework tarafında JSONite denen daha minimal bir kütüphane devreye giriyor — ilk duyduğumda “bu da nereden çıktı” dedim, sonra kaynak koduna bakınca açık konuşayım, baya derli toplu duruyor.

Bu değişikliğin asıl motivasyonu performans değil, güvenlik yüzeyini daraltmak. Microsoft,.NET SDK’nın bağımlılık ağacındaki her bir transitive paketi azaltmaya çalışıyor. VSTest bu hamlenin bir parçası, sonuncusu değil.

Değişmeyen Şeyler — Geriye Uyumluluk Garantisi

Hemen panik yapmadan önce şunu söyleyeyim: VSTest’in wire format‘ı değişmedi. Mesajlar aynı kalıyor. Yanı testhost ile platform arasında gidip gelen paketler, hangı serializer kullanılırsa kullanılsın, yine aynı sırayla yazılıp karşı tarafta okunabiliyor; bu da işin asıl can alıcı tarafı,. Eski sürümlerle yeni sürümler birbirine küsmeden konuşmaya devam ediyor.

  • Eski testhost’lar yeni platformla konuşabiliyor
  • Yeni testhost’lar eski platformla konuşabiliyor (bence en önemlisi)
  • Serileştirme performansı aynı veya daha iyi (özellikle.NET tarafında STJ’nın source generator avantajı sayesinde)

Doğrusu, Yanı bir CI/CD pipeline’ında farklı.NET sürümlerini yan yana çalıştırıyorsanız, ki büyük kurumsal yapılarda bu gayet sıradan bir durum, açıkçası burada korkulacak bir şey yok (inanın bana). Logosoft’ta bir telekom müşterisinde aynı solution içinde net48, net8.0 ve net9.0 hedefleri yan yana koşuyor; böyle senaryolarda Microsoft’un wire format’ı koruması bana kalırsa baya yerinde olmuş.

Etkilenmeyen Projeler: Çoğunluk Burada

Sakın olun, projelerin büyük kısmı hiçbir şey yapmadan yoluna devam edecek. Hangileri? Şey, ilk bakışta kafa karıştırıyor gıbı duruyor ama değil (bizzat test ettim)

  • Newtonsoft.Json’u zaten kullanmayan projeler (yanı modern System.Text.Json‘a geçmiş olanlar)
  • Newtonsoft.Json’u normal bir PackageReference olarak kullanan projeler (en yaygın senaryo)
  • .NET üzerinde koşan veya AppDomain kullanan xUnit ve NUnit projeleri — bunlar zaten explicit reference istiyordu (bu kritik)

Tuhaf ama, Burada can alıcı nokta şu: Eğer projenizde Newtonsoft.Json paket olarak csproj‘da görünüyorsa ve runtime asset’i exclude etmiyorsanız, sizin için aslında hiçbir şey değişmiyor. Build de çalışır, test de koşar; hatta bazen insan “tamam mı bu kadar?” diye soruyor, evet, bu kadar.

Etkilenenler: İşte Asıl Mesele Burada

Şimdi hassas yere geldik. Üç ayrı hata senaryosu var. Iyi tarafı şu: bunlar sessiz sedasız geçmiyor, yanı test koşusunda açık açık patlıyor, TRX raporlarına düşüyor, Azure DevOps ile GitHub test view tarafında da gözünüze çarpıyor. Kötü tarafı mı? Epey can sıkabiliyor.

Bunu biraz açayım.

1. Build Hatası: Eksik Newtonsoft.Json Referansı

Bu en sinsi olanı, hani ilk bakışta “ne oluyor ya” dedirten türden. Diyelim ki test projenizde JObject, JsonConvert gıbı tipleri kullanıyorsunuz ama paketi eklememişsiniz; şimdiye kadar derleniyordu çünkü VSTest’in kopyası transitively sızıyordu (evet, biraz garip bir durumdu), yanı aslında yanlış kullanım vardı ama kimse fark etmiyordu — itiraf edeyim, beklentimin üstündeydi —

Güncellemeden sonra bu iş derlenmiyor. Çözüm tek satır, fazla büyütmeye gerek yok:

<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />

Bunu ilk kez 2022 yılında fark etmiştim. Bir e-ticaret projesinde junior bir arkadaş “Hocam JObject‘i kullanabiliyorum — itiraf edeyim, beklentimin üstündeydi —. Paketi eklememe gerek yok galiba” demişti; ben de o gün “şanslısın, bir bağımlılıktan sızıyor” diye cevap vermiştim. İşte o şans kısmı artık bitiyor, açık konuşayım.

2. Runtime Hatası: FileNotFoundException

Burada iş biraz daha enteresanlaşıyor. Bazı projeler Newtonsoft.Json’u referans olarak ekliyor ama runtime asset’ını bilerek dışarıda bırakıyor:

<PackageReference Include="Newtonsoft.Json" Version="13.0.3">
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>

Doğrusu, Peki neden? Genelde “binary boyutunu küçültelim” ya da “host process kendi kopyasını kullansın” diye düşünülüyor,. Niyet fena değil aslında. VSTest tarafında zaten bir kopya olduğu için bugüne kadar sorun çıkmıyordu; ama artık çıkacak. Şu hata yüzünü gösterecek:

System.IO.FileNotFoundException: Could not load file or assembly 
'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, 
PublicKeyToken=30ad4fe6b2a6aeed'.

Çözüm basit: ExcludeAssets satırını kaldırın. Hepsi bu. Ya da paketi runtime asset’leri dışlanmadan yükleyin; başka sihir aramaya gerek yok. Bu konuyla ilgili Azure Integrated HSM Açık Kaynak Oluyor: Güven Donanımdan yazımıza da göz atmanızı tavsiye ederim.

3. Test Adapter veya Data Collector Yükleme Hatası

Bunu yaşayan biri olarak söyleyeyim, Bu kısım daha çok custom test adapter ya da data collector yazanları ilgilendiriyor. Eğer adapter Newtonsoft.Json kullanıyor ama kendi nuspec‘inde dependency olarak belirtmemişse, yükleme anında patlıyor; hani sessizce geçmesini bekliyorsanız boşa bekliyorsunuz:

Data collector 'SampleDataCollector' threw an exception during 
type loading, construction, or initialization: 
System.IO.FileNotFoundException: Could not load file or assembly 
'Newtonsoft.Json, Version=13.0.0.0...

Eh, Bunu özellikle eski ve içeride yazılmış custom data collector’larda kontrol etmenizi öneririm. Bir bankacılık projesinde uyumluluk loglaması için yazdığımız bir data collector vardı; başka bir vesileyle tam böyle bir bağımlılık problemi yaşamıştık ve debugging süresi iki günü bulmuştu çünkü stack trace pek yol göstermiyordu, yanı insanı biraz oyalar bu tıp şeyler.

Dürüst olmak gerekirse, Evet. Bu konuyla ilgili Kubernetes v1.36: Pod-Level In-Place Resize Beta’da yazımıza da göz atmanızı tavsiye ederim.

Hızlı Karar Tablosu

Aşağıdaki tabloyu bookmark’layın, takım arkadaşlarınızla da paylaşın. Kısa ama iş görüyor. Çünkü bazen mesele tam da bu kadar net oluyor; neyi etkiler, neyi etkilemez, bir bakışta görüyorsunuz. Gereksiz tartışma da azalıyor.

Senaryo Etkilenir mi? Aksiyon
Newtonsoft.Json hiç kullanmıyorum Hayır Yok
Normal PackageReference ile kullanıyorum Hayır Yok
JObject/JsonConvert kullanıyorum ama paket yok Evet (build) Paketi ekle
ExcludeAssets=runtime kullanıyorum Evet (runtime) ExcludeAssets’i kaldır
Custom data collector/adapter geliştiricisiyim Belki Bağımlılığı explicit deklare et
net48 hedefli legacy test projem var Hayır (JSONite devreye giriyor) Yok

Peki neden? Asıl kritik nokta şu: bazen paket projeye ekli gıbı duruyor. Runtime tarafında görünmüyor, sonra da hata pat diye geliyor. Şey, özellikle test altyapısında ya da ara katmanlarda bunu çok gördüm; build geçiyor, sonra çalışma anında sürpriz çıkıyor.

Neyse, çok uzatmayayım. Eğer senaryo tabloda “Hayır” diyorsa genelde rahat davranabilirsiniz, ama “Evet” ya da “Belki” görüyorsanız bir durup bağımlılık zincirini kontrol edin; yoksa sorun sessizce ilerleyip tam en olmadık yerde kendini belli ediyor. Daha fazla bilgi için Bankacılıkta Customer 360: Azure DocumentDB ile Pratik Yol yazımıza bakabilirsiniz.

Türkiye’deki Kurumsal Bakış: Ne Yapmalı?

Şimdi biraz Türkiye tarafına bakalım, çünkü işin pratiği kağıttaki kadar temiz gitmiyor. Danışmanlık verdiğim kurumsal müşterilerin çoğunda hâlâ net48 üzerinde dönen eski test projeleri var; hatta.NET 8’e geçmiş olanlarda bile “test projeleri çalışıyor ya, kurcalamayalım” havası sürüyor. Evet, tam da bu yaklaşım biraz can sıkıyor.

Bu güncelleme, özellikle o “dokunmadıklarımız” kısmında patlayabiliyor. Benim önerim şu: .NET 11 Preview 4’ü production CI’a almadan önce bir staging branch’te dene. İlginç, değil mi? Build matrix’inizde net48, net8.0, net9.0 hedefleri varsa, hepsini tek tek koşturun; çünkü JSONite tarafı.NET Framework için yeni sayılır ve ne kadar test edilmiş olsa da production benzeri bir ortamın yerini tutmuyor, hani o son yüzdeyi ancak gerçek akışta görüyorsunuz. Kubernetes v1.36 Controller Staleness: Artık Daha Az Acı yazımızda bu konuya da değinmiştik.

Şimdi gelelim işin can alıcı noktasına.

Bir bankacılık müşterimde geçen ay buna benzer bir temizlik yaptık (System.Text.Json’a tam geçişti). 800 küsur test projesi olan bir solution’da 23 proje patladı; ortak nokta da şuydu: JObject kullanıp paketi eklememek (kendi tecrübem). Kulağa basit geliyor, ama işin aslı tespiti kolay değil; CI’ı çalıştırmadan bunu yakalamak baya zor oluyor. Daha fazla bilgi için GitHub Copilot CLI: Interactive vs Non-Interactive Mod Farkı yazımıza bakabilirsiniz.

💡 Bilgi: Eğer kurumsal bir projede çalışıyorsanız ve build pipeline’larınızda --warnaserror kullanıyorsanız, bu geçişte CI’nızı kırmamak için önce bir staging branch’te dotnet test çalıştırıp tüm projeleri tarayın. NU1701 ve CS0246 hatalarını filtreleyerek hızlıca etkilenen projeleri bulabilirsiniz.

Pratik Migration Rehberi: 5 Adımda Hazırlık

Aslında, Tamam, teori kısmını biraz kenara bırakalım. Şimdi asıl işe gelelim. Eğer elinizde büyükçe bir solution varsa, ben olsam şu sırayla yürürüm:

  1. Envanter çıkarın: Solution içindeki bütün test projelerini tek tek listeleyin. Hangileri Newtonsoft.Json kullanıyor, hangilerinde explicit PackageReference var, bir bakın; çünkü ilk sürpriz genelde burada çıkıyor.
  2. ExcludeAssets aramaları yapın: Tüm csproj dosyalarında ExcludeAssets geçen satırları grep’leyin. Kulağa basit geliyor ama işin aslı, en problemli yerler çoğu zaman bunlar oluyor.
  3. Custom adapter/collector denetimi: Kendi yazdığınız extension’lar varsa, onların nuspec tarafını da kontrol edin. Şey, bazen sorun ana projede değil de yan taraftaki ufak bir paket tanımında saklanıyor.
  4. Staging build:.NET 11 Preview 4 SDK’yı staging ortamına kurup dotnet test‘i çalıştırın. Hata loglarını TRX’e yazdırın; sonra dönüp bakınca neyin kırıldığını daha net görüyorsunuz, yoksa tahmin oyunu başlıyor.
  5. Toplu fix: Etkilenen projelere PackageReference ekleyip PR olarak gönderin. Tek satırlık değişiklik gıbı duruyor ama commit history’de temiz dursun diye ayrı taşımak bence değer. (bu kritik)

Evet, bu kadar sade görünüyor ama pratikte öyle ölmüyor tabii. Bir yerde eski bir test helper patlıyor, başka yerde transitif paket yüzünden garip bir çakışma çıkıyor (özellikle büyük repolarda bu sahneye çok rastlıyorum), sonra siz de “neden sadece bir referans ekledik de yarım gün gitti?” diye düşünüyorsunuz — dürüst olayım, biraz hayal kırıklığı —

Bu arada konu.NET tarafındaki bağımlılık yönetimine gelmişken, .NET 10’da API Versioning ve OpenAPI: Pratik Entegrasyon yazımda da benzer “bağımlılık temizliği” temasına değinmiştim — System.Text.Json’un ekosistemde nasıl bir konuma geldiğini anlamak isteyenler için iyi bir başlangıç olabilir.

Peki neden bunu özellikle söylüyorum? Çünkü migration işlerinde küçük görünen bağımlılıklar bazen ana hikâyeyi belirliyor; hani şu “bir şey olmaz” dediğiniz satır var ya, işte en çok orası can sıkıyor (ki bu çoğu kişinin gözünden kaçıyor)

Kişisel Görüşüm: Doğru Yön Ama Geç Kalınmış

Şöyle söyleyeyim, Açık konuşayım, bu hamle 2-3 yıl önce gelse daha iyi olurdu. System.Text.Json zaten.NET 5 ile baya olgunlaşmıştı. Microsoft’un büyük SDK işlerinde böyle değişiklikleri ağırdan alması pek şaşırtmıyor, çünkü geriye uyumluluk korkusu çoğu zaman masanın üstündeki diğer her şeyi itiyor.

Yine de sonuç fena değil..NET SDK’nın bağımlılık ağacından her transitive paket çıktığında, supply chain saldırı yüzeyi de biraz daralıyor; hani şu güvenlik ekiplerinin geceleri kafasını kurcalayan kısım var ya, işte o taraf biraz rahatlıyor. CVE-2026-3854: git push Üzerinden GitHub’da RCE Vakası yazımda da değindiğim gıbı, modern dev araçlarında güvenlik hassasiyeti artık boş laf değil (ben de ilk duyduğumda şaşırmıştım). Buradaki Newtonsoft.Json çıkarma işi de aynı zincirin bir halkası gıbı duruyor.

Bir noktada durup şunu da söyleyeyim: JSONite’ı duyuran resmî bir blog post ya da repo ben henüz görmedim. Bu biraz tuhaf geldi, şey… Microsoft bunu daha şeffaf anlatabilirdi, özellikle.NET Framework hedefleyen kurumsal müşteriler için; çünkü production’a giren bir şeyin arkasında ne var, kim yazmış, nasıl ilerliyor görmek isterim — valla güzel iş çıkarmışlar —. Bu konuda biraz daha bilgi gelene kadar gözüm üzerinde olacak.

Bakın, burayı atlarsanız yazının kalanı anlamsız kalır.

Visual Studio 18.8 ve Test Explorer Tarafı

Bir de IDE tarafı var, işin orası da boş değil. Visual Studio 18.8 ile gelen Test Explorer da aynı VSTest motorunu kullandığı için kurallar yine aynı kalıyor; yanı “Run All Tests” tuşuna bastığınız anda testler dağılıyorsa, ilk bakacağınız yer çıktı penceresi, çünkü FileNotFoundException görüyorsanız teşhis çoğu zaman baya net oluyor. Visual Studio 18.5: VSIX Projeleri Artık SDK-Style yazımda da Visual Studio’nün modernleşme sürecine değinmiştim, hani bu Newtonsoft temizliği de o yolun bir parçası gıbı duruyor aslında.

Sıkça Sorulan Sorular

Newtonsoft.Json artık neredeyse tamamen kalkıyor mu.NET’ten?

Hayır, öyle bir şey yok. Sadece.NET SDK’nın kendi bağımlılıklarından çıkarılıyor, yanı sen kendi projenizde istediğin gıbı Newtonsoft.Json kullanmaya devam edebilirsin. Açıkçası paket hâlâ aktif olarak geliştiriliyor — James Newton-King maintain etmeye devam ediyor ve 13.0.x serisi gayet güvenli durumda.

Çok konuştum, örnekle göstereyim.

JSONite ne oluyor, neden.NET Framework için System.Text.Json tercih edilmedi?

Aslında System.Text.Json’un.NET Framework desteği var,. Hani beraberinde epey ağır bir bağımlılık yükü taşıyor — System.Memory, System.Buffers falan. VSTest gıbı test platformlarında bu pek tercih edilen bir şey değil. Bence daha hafif ve self-contained bir çözüm istemek gayet mantıklı. JSONite de tam bu boşluğu dolduran minimal bir JSON serializer olarak devreye giriyor.

Mevcut TRX dosyalarım veya test sonuçlarım bundan etkilenir mi?

Kısacası, bunu yaşayan biri olarak söyleyeyim, Hayır, hiçbir şey değişmiyor. Wire format ve TRX format aynı kalıyor. Eski testhost’lar yeni platformla, yeni testhost’lar eski platformla sorunsuz iletişim kurmaya devam ediyor (bu beni çok şaşırttı). Bu tamamen iç bir implementasyon değişikliği, yanı dışarıdan fark etmen neredeyse imkânsız.

Build kırıldı, hangı versiyonu eklemeliyim?

Eh, En azından 13.0.3 kullanman gerekiyor. 13.0.0’dan eski tüm sürümler vulnerable olarak işaretli. Tecrübeme göre zaten en güncel 13.x sürümüne geçmek en sağlıklısı — çünkü 12.x ve öncesi NuGet’te güvenlik uyarısı veriyor, bu da oldukça can sıkıcı olabiliyor.

Custom test adapter geliştiricisiyim, ne yapmam lazım?

Şöyle söyleyeyim, Eğer adapter’ın Newtonsoft.Json kullanıyorsa, bunu kendi nuspec dosyanda explicit dependency olarak deklare etmen gerekiyor. VSTest’in transitive olarak sağladığı kopyaya güvenme. Açıkçası bu zaten baştan beri yapılması gereken doğru pratikti, sadece şimdi zorunlu hâle geliyor.

Kaynaklar ve İleri Okuma

VSTest is Removing its Newtonsoft.Json Dependency —.NET Blog

System.Text.Json Resmî Dokümantasyonu — Microsoft Learn

microsoft/vstest GitHub Reposu

Garip gelecek ama, Newtonsoft.Json NuGet Sayfası. Sürüm Geçmişi

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

← Onceki Yazi
Bankacılıkta Customer 360: Azure DocumentDB ile Pratik Yol

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İçindekiler
← Bankacılıkta Customer 360: Azu...