Dafür gibt es (theoretisch) eine denkbar einfache Lösung: SPListItem bietet eine Methode CopyTo(destinationUrl) an (http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.copyto.aspx) - leider scheint diese aber nicht (in jedem Fall?) zu funktionieren. Zumindest in meinem Fall (benutzerdefinierte Liste mit benutzerdefiniertem Inhaltstyp UND Attachments - vielleicht erwarte ich einfach auch zu viel von Sharepoint…) tat sie es nicht. Stattdessen erhielt ich folgende Exception: "Source item cannot be found. Verify that the item exist and that you have permission to read it." Eine rasche Recherche bei Google brachte mir die Erkenntnis, dass andere Leute das gleiche Problem auch schon hatten - leider ohne verwertbare Lösungsvorschläge…
Also erstellen wir uns eben selbst eine kleine statische Methode, die das gewünschte tut:
Die Methodensignatur erwartet ein Quellelement und einen Listenname und gibt das kopierte Zielelement zurück:
Zuerst erstellen wir das Zielelement in der angegebenen Liste. Dann gehen wir Schritt für Schritt alle Fields des Quellelementes durch und kopieren diese zum Zielelement:
Achtung! Wir sollten nicht versuchen, readonly Fields zu kopieren und auch die Attachments lassen sich nicht auf diese Weise "abfertigen". Diese behandeln wir folgendermaßen:
Nun noch schnell das Zielelement gespeichert und zurückgegeben - fertig 🙂
So könnte z.B. der Aufruf der Methode aussehen:
Zum besseren Kopieren hier das Ganze nochmal als Text:
public static SPListItem CopyItem(SPListItem sourceItem, string destinationListName)
{
//copy sourceItem to destinationList
SPList destinationList = sourceItem.Web.Lists[destinationListName];
SPListItem targetItem = destinationList.Items.Add();
foreach (SPField f in sourceItem.Fields)
{
if (!f.ReadOnlyField && f.InternalName != "Attachments")
{
targetItem[f.InternalName] = sourceItem[f.InternalName];
}
}
//copy attachments
foreach (string fileName in sourceItem.Attachments)
{
SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
byte[] imageData = file.OpenBinary();
targetItem.Attachments.Add(fileName, imageData);
}
targetItem.Update();
return targetItem;
}
Hi Dorrit,
möchte "Danke" sagen.
Das kann ich demnächst sehr gut gebrauchen 🙂
Liebe Grüsse
aus Köln
Manfred
Hallo Dorrit,
vielen Dank für diesen SEHR hilfreichen Beitrag.
Hat mir aktuell sehr geholfen 😉
LG Tom
[…] showed that I was not the only one struggling with this. Several solutions are available like: https://www.communardo.de/techblog/2008/01/08/sharepoint-listenelement-splistitem-in-eine-andere-list… (you can read the code… ) […]
Hi Dorrit,
The solution works fine. But it does not copy the "Created By" field i.e. when a listitem is copied to another list, the "created by" is set to the system account and not the "created by" column from the source list. I have a requirement where i want to replicate the "Created by" field too.
Hi pankaj, you should be able to solve your problem by using the SPUserToken object. Here you can find a similiar (not just the same but I think you can adapt this) solution: http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/41d34a5e-e53b-4d27-bc0a-4a4bb2107e6a
Cheers, Dorrit
Hallo!
Danke für den hilfreichen Post! Wollte nur noch anmerken, dass beim kopieren ein "Assigned To" Field nicht mitkopiert wird, da (unter Umständen) der User in einer anderen Site Collection eine andere Userid haben kann 😉 )
Ansonsten funktioniert das aber super!
viele Grüße aus München
Johannes
thank you, it was very helpful for me.
OMG.…you are a GENIUS ! Thank you so much for covering this problem, your solution save my day ! I really2 appreciate your effort for this ! 😀
BIG thanks!!!
Hello
I am having trouble implementing the code above. I have two sitecollections and want to copy a list item from one site collection list to another site collection list.
Sitecollection 1name: mySiteCollection1
Sitecollection 2 name: mySiteCollection2
This is my code which is run in Site Collection 1. I have created the event handler and have added it to the GAC and implemented the Feature.
public override void ItemAdded(SPItemEventProperties properties) {
SPListItem approvedItem = CopyItem(properties.ListItem, "http://localhost/mysitecollection2/mysubsite/Contacts/AllItems.aspx");
}
public static SPListItem CopyItem(SPListItem sourceItem, string destinationListName)
{
//copy sourceItem to destinationList
SPList destinationList = sourceItem.Web.Lists[destinationListName];
SPListItem targetItem = destinationList.Items.Add();
foreach (SPField f in sourceItem.Fields)
{
if (!f.ReadOnlyField && f.InternalName != "Contacts")
{
targetItem[f.InternalName] = sourceItem[f.InternalName];
}
}
//copy attachments
foreach (string fileName in sourceItem.Attachments)
{
SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
byte[] imageData = file.OpenBinary();
targetItem.Attachments.Add(fileName, imageData);
}
targetItem.Update();
return targetItem;
}
Thank you
Yoshi
Hello Yoshi, the code is meant for copying items between two lists in the same site. The code line "SPList destinationList = sourceItem.Web.Lists[destinationListName];" won't work between site collections.
Hello
Will it work for two lists in two subsites of the same site collection?
Example:
Subsite A - List 1
To
Subsite B - List 2
Thank you
Yoshi
Hello Yoshi, same problem regarding code line "SPList destinationList = sourceItem.Web.Lists[destinationListName];". Of course you can adapt it in order to bring it to work between different sites.
Hi Dorrit
Thank you for sharing the code above. I have managed to get this to work with 2 identical custom lists in the same site. However, when I add a new list item to List A, it will create approximately 10 identical items in List B. Any clues on how to solve this?
Thank you.
Yoshi
Hello Yoshi, as funny as it sounds: I think you must have done something wrong.
Hello. That is a nce solution, however I can't get it working with External Data column (that contains a reference to external content type). The text comun content is being copied, the external data column stays empty. Do you know if it is possible at all? Cheers.
For External Data columns it has to possible, too. I think you had to verify whether it concerns an External Data column and if so, then put some code there referencing the external content type.
Danke!!!