SharePoint REST API ID Manipulation BUG

Merhabalar,

Bir müşterinin projesi için piyasadaki Content Migration Araçları vasıtasıyla eski ortam’dan(SharePoint 2007 – WSS 3.0) yeni ortama (SharePoint 2016) ortamına liste,kütüphaneler ve diğer içerikleri taşımamız gerekiyordu.

SharePoint Content DB Migration yöntemine  müşteri sıcak bakmadığından  mecburen işi Content Migration Araçlarıyla halletmemiz gerekecekti.

Müşterinin ihtiyacı standard bir taşıma aracının yapamayacağı türdendi.Müşteri Liste ve Kütüphanelerdeki içeriklerin “ID bilgilerinin değişmeden” taşınmasını istemekteydi.Piyasadaki tüm content migration araçlarını denediğimizde bunu sağlayamadığını,”ID” değerini otomatik olarak ayarladığını gördük.

Bu durumda geriye ya müşteriyi Content DB Migration yöntemine  ikna etmek ya da custom bir migration tool yazmak kalıyordu.İlk seçeneği müşteri istemediği  için custom migration tool’unu yazmaya başladım

 

CUSTOM MIGRATION TOOL

Bu toolu C# ile Console Application olarak geliştirdim.Tool 2007 ortamında çalışacak ve liste/kütüphane içeriklerini REST ile 2016 ortamına aktaracaktı.

Tool’u yazdık.Denemelerimizi yaptık.Başarılı sonuçlar vermeye başladı.

90.000 kayıtlık listeyi 18 saat içerisinde(eski sürüm Windows Server sunucusu olduğunu da düşünürsek) aktardığını gözlemledik.

Migration Tool’larının bu kadar büyük listeleri açamadıklarını,açsa bile 90 günde tahmini taşıma süresi ve yarı yolda appcrash olduklarını da düşündüğümüzde 18 saat’te büyük listeleri taşıyor olmak büyük bir olaydı.
ID’ler istediğimiz gibi bir ortamdan diğerine aktarılıyordu.Herhangi bir sıkıntı ile karşılaşmadık.

Ardından Test liste/kütüphanelerden gerçek içerikleri taşımaya başladık.Test ortamında olduğu gibi tüm içerikleri bir ortamdan diğerine aktarıyorduk.

Bu haliyle yazdığım tool işimizi görecekti ve piyasadaki tüm araçların yapamadığını yapıyordu: ID’leri olduğu gibi taşıyordu

Örnek kod(payload):

 

 

SORUNUN ORTAYA ÇIKIŞI

Şimdi gelelim toz pembe’den gerçekliğe…

Listeler’de içerik girişleri esnasında bazı durumlarda(bazı ID’lerde) verilerin kaydedilmediği,kaydet buton’una sürekli basılması durumunda verilerin kaydedildiği gibi bir durum ile karşılaştık J

 

Örneğin;


ID        Title                  Rol      

1          İbrahim            Developer

3          Jane                  Tester

5          Ali                      Manager

 

Yukarıdaki gibi bir örnek listemiz olduğunu ve bu liste içeriğinin de REST API ile ID Manipülasyonu yapılarak taşındığını varsayalım

Bu listeye eğer  yeni bir eleman eklemek istersek,ID olarak “2” değerini vereceğini düşünürsünüz değil mi?

O zaman yanlış düşünüyorsunuz.

 

Çünkü burada ilk giriş yapıldığı için “1” değerini atamaya çalışacaktır.1 ID’li değerimiz olduğu için de bize uyarı mesajı verecektir.REST ile gönderilen ID ile SharePoint’in  ID atama mekanizması arasında bir iletişimsizlik durumu mevcut olmaktadır.

 

REST ile ID Manipülasyonu yaptığımızda SharePoint’in bir şekilde kafası karışır ve “ID göndermek benim işim,bak şimdi kafamı karıştırdın” dermişcesine veri eklemeye çalıştığımızda bize “0x…” ile başlayan uyarılar fırlatır.Bu gayet olağan bir durum gibi gözükse de REST API’de ID değerini post etmemiz engellenmediğinden ötürü ve ID değerini ne gönderirsek gönderelim kabul ettiği için bu bir bug olarak nitelendirilebilir.

 

ID Manipülasyonu tehlikeli bir iştir ve dikkatli olunmadığı vakit liste/kütüphanelerin fonksiyonelliğini yitirmesine sebebiyet verebilir.Mümkün olduğunca ID atama işini SharePoint’e bırakmakta fayda vardır.

 

“Peki bu durumun üstesinden nasıl gelebilirim?

Çözümü yok mudur?

Bu bir bug ise, neden hâlen bugfix yapılmadı?”

 

gibi soruları duyar gibiyim.

 

REST API ile ID manipülasyonu yapılabileceği gözardı edilmiş olabilir.Microsoft’un REST API payload dokümantasyonlarını incelediyseniz,hiçbirinde ID atama işlemini göremezsiniz.

Gel gelelim bu durumun üstesinden nasıl geleceğimize?

  

 

REST API ID Manipülasyonu BugFix

 

Bu sorunu çözmenin şu andaki tek çözümü: EventReceiver yazmaktır

Event Receiver yazarken yakalamanız gereken olay Item oluşturulmadan önceki olay yani “ItemAdding” olayıdır.

 

Eleman daha oluşturulmadan yani ID henüz atanmadan SQL Content DB üzerinden AllListsAux listesindeki NextAvailableId değerini  listede bulunan en son elemanın ID değerini +1 artırarak update etmelisiniz.

 

Tabi bunu yaparken ListID değerini de belirtmek gerekmektedir.

Kodlamaya geçmeden evvel dikkat edilmesi gereken bir husus daha var:

 

Elements.xml dosyasını açtığınızda,Receivers tagına dikkat ediniz

 

 

 

Burada ListTemplateId’yi listenin templateID değerine göre güncelleyebilir veya ListTemplateId’yi kaldırarak tüm listeler için geçerli olmasını sağlayabilirsiniz

 

 

 

 

 

EVENT RECEIVER KODLAMA

 

Bildiğiniz üzere,Event Receiver oluşturulduktan sonra Item Adding olayını kod sayfasında görürsünüz

 

 

 

Öncelikle olarak almamız gereken bilgi Liste bilgisi olacağından ItemAdding olayını aşağıdaki gibi güncelleyelim:

 

 

properties ifadesi ile ilgili elemanın bağlı bulunduğu ve üzerinde işlem yapacağımız Liste’nin bilgisine erişmekteyiz.

 

Bir method yazarak parametre olarak list değişkenini gönderelim

 

 

Event Receiver’ın çalışacağı Site’a bağlantı kurup CAMLQuery yazalım

 

 

Burada yazdığımız kod’da Siteye bağlantı sağlayarak, CAMLQuery’de listenin en son elemanının ID değerini almaktayız

 

Ardından “newid” diye bir sayı tipinde değişken oluşturup değerini en son elemanın değerinden 1 büyük olacak şekilde artıralım

 

 

Bulunduğumuz WebApplication’da Content DB olup olmadığını kontrol edip,[0] ilk sıradaki SQL Content DB’ine bağlantı sağlıyoruz:

 

 

 

Ardından SQL Bağlantısı sağlıyoruz:

 

 

Ve son olarak UpdateCommand oluşturarak WSS_Content DB içerisinde yer alan AllListsAux isimli tablo’da yer alan ListID’si methodumuzun listId parametresine eşit olan kaydın NextAvailableId nümerik değerini daha önceden +1 diyerek listenin en son elemanını artırdığımız değişkenimize atama işlemini yerine getiriyoruz.

 

 

 

 

ItemAdding methodunu da aşağıdaki gibi güncelleyerek event receiver’ımızı tamamlayalım

 

 

Update işleminde dikkat edilmesi gereken AllListsAux isimli tabloda bulunan ilgili listenin ID’si verilerek NextAvailableId sütununu daha önceden +1 olarak artırdığımız değeri atamaktayız.

 

Böylelikle Event Receiver çalıştığında(event receiver’ı bir feature’a bağladığınızı ve aktive ettiğinizi varsayayıyorum) veri ekleme işi yapan kullanıcı hata almayacak ve ID’ler düzgün bir şekilde atanacaktır.

 

KODUN TAMAMI

TestEventReceiver.cs:

 

 

 

Elements.xml:

 

 

 

SONUÇ

 

ID(Kimlik) Manipülasyonu önerilen bir yöntem değildir.

Her ne kadar Event Receiver yöntemiyle SQL Update işlemiyle bu sorunu çözmüş olsakta, SharePoint’in kendi ataması gereken ID’lerin hiçbir suretle değiştirilmemesi gerekmektedir.

Eğer Liste ve Kütüphaneler’de yer alan ID’ler hiçbir suretle değişmeyecek,taşınacak yeni sistemde de birebir kullanılması sağlanacak ise Content DB Migration yöntemi kullanılarak Step by Step Migration(SP2007>SP2010>SP2013>SP2016) yapılmalıdır.

Eğer ki migration yapılamaz veya müşteri tarafında migration yapılması istenmezse,bu yöntemi Content DB Migration yapılamayacak durumlarda kullanabilirsiniz.

 

Bir yorum ekleyin