Transferir itens da lista com anexos de SharePoint 2003 a uma lista existente no SharePoint 2007

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

Pergunta

Eu tenho itens em uma lista em um site do SharePoint 2003 que eu preciso adicionar a uma lista existente em um site de 2007. Os itens têm anexos.

Como isso pode ser feito usando PowerShell ou C #?

Foi útil?

Solução

Acabei usando um programa C #, em conjunto com os serviços SharePoint web para fazer isso. Eu também usei os métodos de extensão (GetXElement, GetXMLNode) no blog do Eric White aqui para converter entre XMLNodes e XElements que fez o XML a partir do SharePoint mais fácil trabalhar com.

Segue-se um modelo para a maior parte do código necessário para os dados da lista de transferência, incluindo anexos, a partir de uma lista do SharePoint (ou 2003 ou 2007) para outra:

1) Este é os anexos movimentos de código depois que um novo item foi adicionado à 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 percorre a antiga lista e preenche SharePoint o novo.

    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) Diversos código de suporte para esta amostra.

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

Outras dicas

Eu provavelmente tentar implementar algo com os serviços web - Eu sei que para 2007 as urls de fixação aparecer no atributo ows_Attachements, e uma vez que você tem que você pode fazer um padrão bastante download / upload. Tem sido um tempo desde que eu fiz qualquer coisa com 2003, mas eu não acho que isso é um novo campo.

Se você tiver problemas para obter os dados corretos a partir de 2003, você poderia sempre migrar todo o site a 2007 e, em seguida, extrair os dados que pretende utilizando a mais recente API.

Você já tentou salvar a lista ( "com conteúdo") como um modelo, salvar esse arquivo para os templates de portal 2007, em seguida, criar uma nova lista usando esse "custom" modelo? Isso não vai funcionar se os anexos e itens totalizam mais de 10 MB, e eu não estou 100% de certeza que isso vai funcionar para 2003> 2007. Ele deve tomar <10 minutos, por isso vale a pena tentar se você não tem já.

Eu tive que criar este projeto: http://sourceforge.net/projects/splistcp para uma tarefa semelhante, mas, a fim de manter o tempo modificado e criado eo usuário Eu tive que usar a API local no destino. O benefício de sua abordagem parece ser o suporte mais fácil tanto para 2003 e 2007 como a fonte.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top