Trasferisci elementi dell'elenco con allegati da SharePoint 2003 a un elenco esistente in SharePoint 2007

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

Domanda

Ho elementi in un elenco in un sito di SharePoint 2003 che devo aggiungere a un elenco esistente in un sito del 2007. Gli articoli hanno allegati.

Come può essere realizzato usando PowerShell o C #?

È stato utile?

Soluzione

Ho finito per usare un programma C # insieme ai servizi web di SharePoint per raggiungere questo obiettivo. Ho anche usato i metodi di estensione (GetXElement, GetXmlNode) sul blog di Eric White qui per la conversione tra XMLNodes e XElements che ha reso più semplice il funzionamento di XML da SharePoint.

Di seguito è riportato un modello per la maggior parte del codice necessario per trasferire i dati dell'elenco, inclusi gli allegati, da un elenco di SharePoint (2003 o 2007) a un altro:

1) Questo è il codice che sposta gli allegati dopo che un nuovo elemento è stato aggiunto all'elenco di destinazione.

// 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) Codice che scorre nel vecchio Elenco di SharePoint e popola il nuovo.

    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) Codice di supporto vario per questo esempio.

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

Altri suggerimenti

Probabilmente proverei a implementare qualcosa con i servizi Web: so che per il 2007 gli URL degli allegati vengono visualizzati nell'attributo ows_Attachements e, una volta che hai, puoi fare un download / upload abbastanza standard. È passato un po 'di tempo da quando ho fatto qualsiasi cosa con il 2003, ma non credo che sia un nuovo campo.

Se hai difficoltà a ottenere i dati giusti dal 2003, puoi sempre migrare l'intero sito al 2007 e quindi estrarre i dati desiderati utilizzando l'API più recente.

Hai provato a salvare l'elenco (" con contenuto ") come modello, salvare quel file nei modelli del portale 2007, quindi creare un nuovo elenco utilizzando tale " personalizzato < !> quot; modello? Ciò non funzionerà se gli allegati e gli elementi superano i 10 MB e non sono sicuro al 100% che funzionerà per il 2003 & GT; 2007. Dovrebbe volerci & Lt; 10 minuti, quindi vale la pena provare se non lo hai già fatto.

Ho dovuto creare questo progetto: http://sourceforge.net/projects/splistcp per un compito simile, ma per mantenere il tempo e l'utente modificati e creati ho dovuto usare l'API locale sulla destinazione. Il vantaggio del tuo approccio sembra essere il supporto più semplice sia per il 2003 che per il 2007 come fonte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top