İçeriğe geç →

Asp.NET Web API’da Circular Reference Handling

Merhaba arkadaşlar.

Yılbaşından sonra çıkacak olan Asp.Net Web API kitabımıza odaklandığım için bu aralar fazla makale yazamıyorum. Fakat e-mail aracılığı ile gelen sorular ve benimde bir kaç projede karşı karşıya gelmem nedeniyle “Self referencing loop detected” problemini nasıl handle edebileceğimizi kitabın bir bölümünden alarak makale olarak koymak istedim. 🙂

Circular referans yani döngüsel referans, farklı modellerin birbirlerini referans olarak görmesidir. Özellikle entity framework kullanılarak oluşturulan modeller içerisindeki, navigation property’ler üzerinde görülmektedir. Dilerseniz aşağıdaki model kod bloğuna bir bakalım:

Yukarıdaki kod bloğunda bulunan Customer ve Order modellerinin navigation property’lerine baktığımızda Customer’ın Order tipinde bir collection’a sahip olduğunu, Order’ın ise Customer tipinde döngüsel bir navigation property’e sahip olduğunu görebiliriz.

İlgili serializer bu modeli serialize etmeye çalıştığında ise aşağıdaki hatayı verecektir:

self loop reference

Serialize işlemi sırasında birbirlerini döngüsel olarak referans gösteren iki navigation property’den dolayı serialize işlemi bir loop’a girmekte ve bu sebeple ilgili serializer bu döngüyü nasıl handle edebileceğini bilmediği için “Self referencing loop detected for property” hatasını vermektedir.

Asp.NET Web API içerisinde bu sorunu handle edebilmek için üç farklı yol vardır:

1) Global Olarak Circular Referans’ı Ignore Etmek

Json.NET serializer’ın, serializer ayarlarında aşağıdaki kod bloğu ile global düzeyde circular referans’ı ignore edebiliriz.

Yukarıdaki kod bloğu ile loop referans’a sebep veren property, ilgili referans bilgisini kaybetmiş olacak ve aşağıdaki gibi bir json çıktısı ediyor olacağız:


2) Global Olarak Circular Referans’ı Korumak Etmek

Json.NET serializer’ın serializer ayarlarında, circular referans’ı ignore edebildiğimiz gibi preserving ayarı ile bunu global düzeyde koruyabilmemizde mümkündür.

Yukarıdaki kod bloğu ile circular referans’a sebep olabilecek referansları nasıl handle edebileceğini ilgili serializer’a bildiriyoruz ve bunun sonucunda ise json çıktısı biraz değişmiş olacak.

Yukarıdaki json çıktısında görebileceğimiz üzere PreserveReferencesHandling ayarı ile “$id” ve “$ref” değerleri tüm referans bilgilerini tutabilmektedir ve böylece döngüsel referans hatasına sebep olabilecek problemin önüne geçebilmektedir.

NOT: Unutmamalıyız ki PreserveReferencesHandling ayarı ile json çıktısı üzerinde referansları tutabilmesi için oluşturulmuş olan bu object referansları bir JSON standartı değildir. Bu nedenle bu işlemi yapmadan önce ilgili client’ın gelen json sonucunu nasıl parse edebileceğini bilmesi gerekmektedir.

3) Model veya Property Düzeyinde Circular Referans’ı Ignore Ermek veya Korumak

Bu yöntemde ise global düzey yerine işi biraz daha spesifikleştirerek model veya property düzeyinde attribute’ler aracılığı ile gerçekleştirebilmek mümkündür. Dilerseniz şimdi hemen Customer sınıfına bir göz atalım:

JsonIgnore ve IgnoreDataMember attribute’leri ile hem Json.Net için hem de XmlSerializer için serialize işlemi sırasında bu property’i ignore etmesini bildirdik. Bu sayede serialize işlemi sırasında bu property serialize işlemine tabi olmayacaktır.

Şimdide ilgili referansı koruyabilmek için yapılması gerekene bir bakalım:

Model düzeyinde eklemiş olduğumuz JsonObject(IsReference = true) attribute’ü ile ilgili Orders referansını koruması gerektiğini bildirdik. Aynı işlemi XmlSerializer için ise [DataContract(IsReference=true)] attribute’ü ile yapabilmekte mümkündür. Unutmayalım, DataContract attribute’ünü eklediğimizde serializer opt-in yaklaşımına göre davranacaktır ve serialize işlemine tabi olmasını istediğimiz property’lere DataMember attribute’ünü eklememiz gerekmektedir.

Dilerseniz şimdi birde XML için oluşacak sonuca [DataContract(IsReference=true)] attribute’ünü ekleyerek bir bakalım. Öncelikle Customer modelimizi opt-in yaklaşımına göre hazırlayalım:

Modelimizi oluşturduk ve şimdi serialize işlemi sonucunda oluşacak olan XML çıktısına bir bakalım:

XML çıktısında gördüğümüz üzere “z:Id” ve “z:Ref” attribute’leri üzerinde referans değerleri tutulmaktadır.

Umarım faydalı bir makale olmuştur.

Bu makale toplam (1251) kez okunmuştur.

8
1



Kategori: Asp.Net Web API

Tek Yorum

  1. Begüm Begüm

    Yazınız ve bilgilendirme için çok teşekkür ederim, çok işime yaradı 🙂
    Başarılar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.