Transférer des éléments de la liste avec des pièces jointes à partir de SharePoint 2003 vers une liste existante dans SharePoint 2007

StackOverflow https://stackoverflow.com/questions/826999

Question

J'ai des éléments dans une liste d'un site SharePoint 2003 que je dois ajouter à une liste existante d'un site 2007. Les éléments ont des pièces jointes.

Comment cela peut-il être réalisé avec PowerShell ou C #?

Était-ce utile?

La solution

Pour ce faire, j’ai utilisé un programme C # conjointement avec les services Web SharePoint. J'ai également utilisé les méthodes d'extension (GetXElement, GetXmlNode) sur le blog d'Eric White ici pour convertir entre XMLNodes et XElements, ce qui a facilité l'utilisation du code XML de SharePoint.

Vous trouverez ci-dessous un modèle pour la plupart des codes nécessaires au transfert de données de liste, y compris les pièces jointes, d’une liste SharePoint (2003 ou 2007) à une autre:

1) C'est le code qui déplace les pièces jointes après l'ajout d'un nouvel élément à la liste des cibles.

// Adds attachments from a list item in one SharePoint server to a list item in another SharePoint server.
//   addResults is the return value from a lists.UpdateListItems call.
private void AddAttachments(XElement addResults, XElement listItem)
{
    XElement itemElements = _listsService2003.GetAttachmentCollection(_listNameGuid, GetListItemIDString(listItem)).GetXElement();

    XNamespace s = "http://schemas.microsoft.com/sharepoint/soap/";

    var items = from i in itemElements.Elements(s + "Attachment")
                select new { File = i.Value };

    WebClient Client = new WebClient();
    Client.Credentials = new NetworkCredential("user", "password", "domain");

    // Pull each attachment file from old site list and upload it to the new site list.
    foreach (var item in items)
    {

        byte[] data = Client.DownloadData(item.File);
        string fileName = Path.GetFileName(item.File);
        string id = GetID(addResults);
        _listsService2007.AddAttachment(_newListNameGuid, id, fileName, data);
    }
}

2) Code qui parcourt l'ancienne liste SharePoint et remplit la nouvelle.

    private void TransferListItems()
    {

        XElement listItems = _listsService2003.GetListItems(_listNameGuid, _viewNameGuid, null, null, "", null).GetXElement();

        XNamespace z = "#RowsetSchema";
        foreach (XElement listItem in listItems.Descendants(z + "row"))
        {
            AddNewListItem(listItem);
        }
    }

    private void AddNewListItem(XElement listItem)
    {
        // SharePoint XML for adding new list item.
        XElement newItem = new XElement("Batch",
            new XAttribute("OnError", "Return"),
            new XAttribute("ListVersion", "1"),
            new XElement("Method",
                new XAttribute("ID", "1"),
                new XAttribute("Cmd", "New")));

        // Populate fields from old list to new list mapping different field names as necessary.
        PopulateFields(newItem, listItem);

        XElement addResults = _listsService2007.UpdateListItems(_newListNameGuid, newItem.GetXmlNode()).GetXElement();

        // Address attachements.
        if (HasAttachments(listItem))
        {
            AddAttachments(addResults, listItem);
        }
    }

    private static bool HasAttachments(XElement listItem)
    {
        XAttribute attachments = listItem.Attribute("ows_Attachments");

        if (System.Convert.ToInt32(attachments.Value) != 0)
            return true;

        return false;
    }

3) Code de support divers pour cet exemple.

    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using System.Xml.Linq;
    using System.Net;
    using System.IO;

    // This method uses an map List<FieldMap> created from an XML file to map fields in the
    // 2003 SharePoint list to the new 2007 SharePoint list.
    private object PopulateFields(XElement batchItem, XElement listItem)
    {
        foreach (FieldMap mapItem in FieldMaps)
        {
            if (listItem.Attribute(mapItem.OldField) != null)
            {
                batchItem.Element("Method").Add(new XElement("Field",
                    new XAttribute("Name", mapItem.NewField),
                        listItem.Attribute(mapItem.OldField).Value));
            }
        }

        return listItem;
    }

    private static string GetID(XElement elem)
    {
        XNamespace z = "#RowsetSchema";

        XElement temp = elem.Descendants(z + "row").First();

        return temp.Attribute("ows_ID").Value;
    }

    private static string GetListItemIDString(XElement listItem)
    {
        XAttribute field = listItem.Attribute("ows_ID");

        return field.Value;
    }

    private void SetupServices()
    {
        _listsService2003 = new SPLists2003.Lists();

        _listsService2003.Url = "http://oldsite/_vti_bin/Lists.asmx";
        _listsService2003.Credentials = new System.Net.NetworkCredential("username", "password", "domain");

        _listsService2007 = new SPLists2007.Lists();

        _listsService2007.Url = "http://newsite/_vti_bin/Lists.asmx";
        _listsService2007.Credentials = new System.Net.NetworkCredential("username", "password", "domain");

    }

    private string _listNameGuid = "SomeGuid";      // Unique ID for the old SharePoint List.
    private string _viewNameGuid = "SomeGuid";      // Unique ID for the old SharePoint View that has all the fields needed.
    private string _newListNameGuid = "SomeGuid";   // Unique ID for the new SharePoint List (target).

    private SPLists2003.Lists _listsService2003;    // WebService reference for the old SharePoint site (2003 or 2007 is fine).
    private SPLists2007.Lists _listsService2007;    // WebService reference for the new SharePoint site.

    private List<FieldMap> FieldMaps;   // Used to map the old list to the new list. Populated with a support function on startup.

    class FieldMap
    {
        public string OldField { get; set; }
        public string OldType { get; set; }
        public string NewField { get; set; }
        public string NewType { get; set; }
    }

Autres conseils

J'essaierais probablement d'implémenter quelque chose avec les services Web. Je sais que pour 2007, les URL de pièce jointe apparaissent dans l'attribut ows_Attachements, et une fois que vous avez cela, vous pouvez effectuer un téléchargement assez standard. Cela fait longtemps que je n’ai rien fait avec 2003, mais je ne pense pas que ce soit un nouveau domaine.

Si vous ne parvenez pas à obtenir les bonnes données à partir de 2003, vous pouvez toujours migrer l'intégralité du site vers 2007, puis extraire les données souhaitées à l'aide de la dernière API.

Avez-vous essayé d'enregistrer la liste (" avec le contenu ") en tant que modèle, enregistrez ce fichier dans les modèles de portail 2007, puis créez une nouvelle liste à l'aide de cette " custom < !> quot; modèle? Cela ne fonctionnera pas si le nombre de pièces jointes et d'éléments dépasse 10 Mo, et je ne suis pas sûr à 100% que cela fonctionnera pour 2003 & Gt; 2007. Cela devrait prendre & Lt; 10 minutes, donc ça vaut le coup d'essayer si vous ne l'avez pas déjà fait.

Je devais créer ce projet: http://sourceforge.net/projects/splistcp pour une tâche similaire, mais afin de conserver l'heure modifiée et créée et l'utilisateur, je devais utiliser l'API locale sur la destination. L’avantage de votre approche semble être un support plus facile pour 2003 et 2007 en tant que source.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top