Dziś pokażę Wam jak wykonać Kopiowanie elementów listy SharePoint pomiędzy różnymi site. Kilka dni temu miałem problem ze stosunkowo prostą rzeczą w SharePoint, prostą jak się okazało tylko z pozoru. Potrzebowałem EventReceivera, który by przenosił element listy do archiwum.

Sprawa wydaje się prosta, EventReceiver we właściwościach elementu dla którego działa wystawia nam oczywistą metodę CopyTo, która działa doskonale o ile chcemy przenieść element, ale z jeden biblioteki, ale kiedy chcemy skorzystać z niej dla list rzuci wyjątkiem. Muszę przyznać, że było to dla mnie spore zaskoczenie, bo zawsze wszyscy mówili, że biblioteki to takie inne listy. Co możemy zrobić? Pierwszy i naturalny wybór to SharePoint designer. No cóż tu kolejna niespodzianka, bo okazuje się, że bez własnej akcji w standardowych akcjach SharPoint designera nie znajdziemy kopiowania z jednej listy SharePoint do listy w innym site. No cóż wróćmy w takim razie do naszego EventReceivera. Okazało się, przynajmniej w moim przypadku, że mam tylko jedną możliwość. Trzeba kopiować kolumnę po kolumnie do docelowej listy. Dodatkowo w ten sposób można kopiować załączniki podpięte pod element listy.

Rozwiązanie było robione pod SharePoint foundation. W SharePoint w wersji standard oraz Enterprise mamy inne opcje jak „wyślij do”, Centrum Rekordów lub przenoszenie zestawów dokumentów w SharePoint designer, ale nie miałem okazji sprawdzić możliwości dla tego konkretnego problemu. Poniżej kod rozwiązania.

Trzeba pamiętać, że wszystkie kolumny źródłowe muszą istnień w liście docelowej inaczej nasz kod się wysypie.

namespace SharePointProject3.EventReceiver1
{
///
/// List Item Events
///
public class EventReceiver1 : SPItemEventReceiver
{
///
/// An item was updated.
///
public override void ItemUpdated(SPItemEventProperties properties)
{
base.ItemUpdated(properties);
try
{
CopyItem(properties.ListItem, properties.SiteId);
}
catch (Exception)
{
throw;
}
}
private SPListItem CopyItem(SPListItem sourceItem, Guid guid)
{
using (SPSite site = new SPSite(guid))
{
using (SPWeb web = site.AllWebs["DesinationSite"])
{
SPList destinationList = web.Lists["DesitnationList"];
SPListItem destinationItem = destinationList.Items.Add();
foreach (SPField field in sourceItem.Fields)
{
if (!field.ReadOnlyField & field.InternalName != "Attachments" & null != sourceItem[field.InternalName])
{
destinationItem[field.InternalName] = sourceItem[field.InternalName];
}
}
destinationItem.Update();
//Copy attachments
foreach (string fileName in sourceItem.Attachments)
{
SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
byte[] imageData = file.OpenBinary();
destinationItem.Attachments.Add(fileName, imageData);
}
destinationItem.Update();
return destinationItem;
}
}
}
}
}
view raw EventReceiver1 hosted with ❤ by GitHub

Jak widać nie mamy zbyt dużo kodu, a kopiowanie elementów listy SharePoint stało się całkiem proste. Zachęcam do własnych testów.

Aktualizacja 18/04/2016
Warto zwrócić uwagę na jedną ważną rzecz. Do niedawna można było stworzyć EventReceiver jako Sandbox Solution i dzięki temu wykorzystać go w SharePoint online w chmurze Office 365. Niestety kilka dni temu boleśnie się przekonałem, że ta opcja już nie działa i solution z takim rozwiązaniem nie będzie mogło być aktywowane, dostaniemy błąd… Szkoda bo to było stosunkowo szybkie i bardzo użyteczne rozwiązanie pewnych sytuacji.