Transferir elementos de la lista con archivos adjuntos de SharePoint 2003 a una lista existente en SharePoint 2007

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

Pregunta

Tengo elementos en una lista en un sitio de SharePoint 2003 que necesito agregar a una lista existente en un sitio de 2007. Los artículos tienen archivos adjuntos.

¿Cómo se puede lograr esto usando PowerShell o C #?

¿Fue útil?

Solución

Terminé usando un programa C # junto con los servicios web de SharePoint para lograr esto. También utilicé los métodos de extensión (GetXElement, GetXmlNode) en el blog de Eric White aquí para convertir entre XMLNodes y XElements, lo que facilitó el trabajo del XML de SharePoint.

A continuación se muestra una plantilla para la mayoría del código necesario para transferir datos de la lista, incluidos los archivos adjuntos, de una Lista de SharePoint (2003 o 2007) a otra:

1) Este es el código que mueve los archivos adjuntos después de que se haya agregado un nuevo elemento a la lista de destino.

// 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) Código que recorre la antigua lista de SharePoint y completa la nueva.

    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) Código de soporte misceláneo para esta muestra.

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

Otros consejos

Probablemente intente implementar algo con los servicios web: sé que para 2007 las URL de los archivos adjuntos se muestran en el atributo ows_Attachements, y una vez que tenga eso, puede hacer una descarga / carga bastante estándar. Ha pasado un tiempo desde que hice algo con 2003, pero no creo que sea un campo nuevo.

Si tiene problemas para obtener los datos correctos de 2003, siempre puede migrar todo el sitio a 2007 y luego extraer los datos que desea utilizando la última API.

¿Ha intentado guardar la lista (" con contenido ") como plantilla, guarde ese archivo en las plantillas del portal de 2007, luego cree una nueva lista utilizando esa " custom < !> quot; ¿modelo? Eso no funcionará si los archivos adjuntos y los elementos suman más de 10 MB, y no estoy 100% seguro de que eso funcione para 2003 & Gt; 2007. Debería tomar & Lt; 10 minutos, por lo que vale la pena intentarlo si aún no lo ha hecho.

Tuve que crear este proyecto: http://sourceforge.net/projects/splistcp para una tarea similar, pero para mantener el tiempo y el usuario modificado y creado tuve que usar la API local en el destino. El beneficio de su enfoque parece ser un soporte más fácil para 2003 y 2007 como fuente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top