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; | |
} | |
} | |
} | |
} | |
} |
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.