No two choices should have the same ID at Microsoft.SharePoint.ApplicationPages.ChoiceComparerWithDefaultGroup.Compare

Sharepoint listeye yeni bir field eklemek/çıkarmak istediğinizde karşılaşabileceğiniz bu hata (yukarıda) açıklayıcı bir hata mesajı içermesine rağmen hangi alanın conflict'e düştüğünü söylememesi yönüyle de biraz yetersizdi.


Bunun sorunu aşmak adına hata mesajında görülen microsoft assembly'sini reflector ile açıp hata hakkında daha fazla bilgi almaya çalışalım. Reflector'da (yukarıda) görüldüğü üzere compare edilen item'ların group-name-id attribute'ları başka bir item'da da aynı ise bu hata mesajı ile karşılaşılıyor. Bu da demektir ki listelerde kullanılan field'lardan bazıları bu 3 özellik yönüyle bir veya daha fazla sayıda clone'a sahip. Bu muhtemelen web arayüzü kullanılmadan hazırlanmış ve içerisinde duplicate satır unutulmuş setup script'lerimizden kaynaklanabilir.

Önce conflict'e neden olan field'ları listeleyen minik bir console application ile sorunlu alanları listeleyelim. Kodu yazarken dikkat edeceğimiz nokta reflector'dan da gördüğümüz üzere compare edilen item'lardan 3 attribute'u da bir başka item ile aynı olan item'ları bulmak. Bunun için .net ile gelen Dictionary class'ını kullanıp key olarak bu 3 attribute'u merge edip item'ı da value olarak geçebiliriz. Dictionary sınıfı aynı key ile gelen bir başka field'ı kabul etmeyip exception fırlatacak ve biz de bu exception'ları yakalayıp "işte sana conflict alanlar bunlar" diye loglayacağız.


// Author: Ergin BULUT
// Feel free to use this code.
namespace ConflictIdChecker
{
class Program
{
static StreamWriter logWriter;

static void Main(string[] args)
{
logWriter = File.CreateText("conflictIds.log");

using (SPSite site = new SPSite("http://www.example.com"))
{
using (SPWeb web = site.OpenWeb())
{
Dictionary<string, SPField> dict = new Dictionary<string, SPField>();

foreach (SPField field in web.Fields)
{
string key = String.Format("{0}/{1}/{2}", field.InternalName, field.Group, field.Id);

try
{
dict.Add(key, field);
}
catch
{
LogConflictItem(field);
Console.WriteLine("Conflict Item: {0}", key);
}
}
}
}

logWriter.Flush();
logWriter.Close();
}

static void LogConflictItem(SPField field)
{
logWriter.WriteLine(String.Format("Field InternalName='{0}' ID='{1}' Group='{2}'", field.InternalName, field.Id, field.Group));
}
}
}


Yukarıdaki mini uygulama ile hataya sebep olan alanları log dosyasından görebilir, düzeltebilir ve listedeki işlemlerimize kaldığımız yerden devam edebiliriz.

Not: Duplicate kayıt içeren script'imizi düzeltmeyi unutmayalım.

0 yorum: