Programatically move documents to document library along with metadata columns and version history

%3CLINGO-SUB%20id%3D%22lingo-sub-98027%22%20slang%3D%22en-US%22%3EProgramatically%20move%20documents%20to%20document%20library%20along%20with%20metadata%20columns%20and%20version%20history%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-98027%22%20slang%3D%22en-US%22%3E%3CP%3EHi%20Team%2C%3C%2FP%3E%3CP%3ENeed%20inputs%20in%20moving%20a%20copy%20of%20document%20along%20with%20its%20metadata%20columns%20and%20version%20history%20to%20a%20different%20document%20library%20using%20C%23%20Console%20App%20(CSOM).%3C%2FP%3E%3CP%3EWe%20are%20automating%20a%20scenario%20where%20we%20identify%20documents%20based%20on%20the%20document%20URL.%20Once%20identified%20%2C%20we%20need%20to%20move%20the%20document%20to%20a%20different%20document%20library%20along%20with%20the%20metadata%20columns%20and%20version%20history.%26nbsp%3B%3C%2FP%3E%3CP%3EI%20was%20successful%20in%20reading%20the%20columns%20and%20associated%20data%20for%20the%20document%20using%20the%20below%20code.%3C%2FP%3E%3CP%3Eprivate%20static%20Dictionary%3CSTRING%3E%26gt%3B%20getListData(ClientContext%20ctxObject%2Cstring%20libraryName)%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20var%20list%20%3D%20ctxObject.Web.Lists.GetByTitle(libraryName)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20FieldCollection%20fields%20%3D%20list.Fields%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20ctxObject.Load(fields)%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20ctxObject.ExecuteQuery()%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20var%20columns%20%3D%20new%20List%3CSTRING%3E%20%7B%20%22ID%22%20%7D%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20foreach(var%20f%20in%20fields)%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20if%20(f.InternalName.StartsWith(%22_%22)%20%7C%7C%20f.InternalName.StartsWith(%22ows%22))%20continue%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20if((f.FieldTypeKind%20%3D%3D%20FieldType.Text)%7C%7C%20(f.FieldTypeKind%3D%3D%20FieldType.DateTime)%20%7C%7C%20(f.FieldTypeKind%3D%3DFieldType.User))%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20columns.Add(f.InternalName)%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7D%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20List%3CEXPRESSION%3E%3CFUNC%3E%3CLISTITEMCOLLECTION%3E%26gt%3B%26gt%3B%20allIncludes%20%3D%20new%20List%3CEXPRESSION%3E%3CFUNC%3E%3CLISTITEMCOLLECTION%3E%26gt%3B%26gt%3B()%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20foreach(var%20c%20in%20columns)%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20allIncludes.Add(items%20%3D%26gt%3B%20items.Include(item%20%3D%26gt%3B%20item%5Bc%5D))%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20ListItemCollection%20listItems%20%3D%20list.GetItems(CamlQuery.CreateAllItemsQuery())%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20ctxObject.Load(listItems%2C%20allIncludes.ToArray())%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20ctxObject.ExecuteQuery()%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20var%20sd%20%3D%20listItems.ToDictionary(k%20%3D%26gt%3B%20k%5B%22Title%22%5D%20as%20string%2C%20v%20%3D%26gt%3B%20v.FieldValues)%3B%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20foreach(var%20i%20in%20sd.Keys)%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20foreach(var%20c%20in%20columns)%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20Console.WriteLine(%22%7B0%7D%3A%7B1%7D%22%2C%20c%2C%20sd%5Bi%5D%5Bc%5D)%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7D%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20return%20sd%3B%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%7D%26nbsp%3B%3C%2FLISTITEMCOLLECTION%3E%3C%2FFUNC%3E%3C%2FEXPRESSION%3E%3C%2FLISTITEMCOLLECTION%3E%3C%2FFUNC%3E%3C%2FEXPRESSION%3E%3C%2FSTRING%3E%3C%2FSTRING%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EBut%20not%20sure%20how%20to%20create%20the%20above%20fetched%20columns%20and%20associated%20data%20along%20with%20the%20document%20in%20the%20new%20document%20library%20.%20Please%20suggest%20possible%20design%20patterns%20and%20any%20code%20artifacts%20that%20support%20this%20kind%20of%20scenario.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThanks%20and%20Regards%2C%3C%2FP%3E%3CP%3ESivapratap%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-98027%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EDeveloper%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-99840%22%20slang%3D%22en-US%22%3ERe%3A%20Programatically%20move%20documents%20to%20document%20library%20along%20with%20metadata%20columns%20and%20version%20hist%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-99840%22%20slang%3D%22en-US%22%3E%3CP%3EYou%20Could%20use%20Get%20template%20which%20is%20getting%20the%20whole%20site%20as%20xml.%3C%2FP%3E%3CP%3Ethen%20apply%20template%20to%20add%20everything%20to%20the%20site.%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3Ein%20the%20xml%20you%20can%20remove%20the%20items%20you%20do%20not%20want%20to%20copy%20to%20the%20other%20site.%20it%20is%20really%20easy%20Vesa%20Juvonen%20and%20his%20team%20putted%20out%20a%20lot%20of%20howto's%20about%20pnp%20provisioning.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-98239%22%20slang%3D%22en-US%22%3ERe%3A%20Programatically%20move%20documents%20to%20document%20library%20along%20with%20metadata%20columns%20and%20version%20hist%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-98239%22%20slang%3D%22en-US%22%3EHi%2C%3CBR%20%2F%3E%3CBR%20%2F%3ESorry%20to%20ask.%20I%20am%20not%20exactly%20clear%20on%20what%20PnP%20does.%20To%20be%20frank%2C%20after%20seeing%20your%20comment%20i%20started%20browsing%20about%20what%20exactly%20PnP%20is.%20Can%20you%20share%20artifacts%20on%20how%20to%20use%20PnP%20to%20replicate%20document%20library%20%3F%3CBR%20%2F%3E%3CBR%20%2F%3EMany%20Thanks%2C%3CBR%20%2F%3ESivapratap.%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-98237%22%20slang%3D%22en-US%22%3ERe%3A%20Programatically%20move%20documents%20to%20document%20library%20along%20with%20metadata%20columns%20and%20version%20hist%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-98237%22%20slang%3D%22en-US%22%3E%3CP%3EIt%20is%20in%20the%20same%20site%20.%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-98198%22%20slang%3D%22en-US%22%3ERe%3A%20Programatically%20move%20documents%20to%20document%20library%20along%20with%20metadata%20columns%20and%20version%20hist%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-98198%22%20slang%3D%22en-US%22%3E%3CP%3EAs%20Juan%20Carlos%20Mentioned%20PnP%20is%20your%20friend!%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-98149%22%20slang%3D%22en-US%22%3ERe%3A%20Programatically%20move%20documents%20to%20document%20library%20along%20with%20metadata%20columns%20and%20version%20hist%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-98149%22%20slang%3D%22en-US%22%3EWhy%20not%20using%20the%20PnP%20to%20replicate%20your%20document%20library%20and%20the%20create%20the%20code%20required%20to%20move%20the%20documents%20from%20the%20source%20to%20the%20destination%3F%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-98079%22%20slang%3D%22en-US%22%3ERe%3A%20Programatically%20move%20documents%20to%20document%20library%20along%20with%20metadata%20columns%20and%20version%20hist%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-98079%22%20slang%3D%22en-US%22%3EIs%20the%20different%20library%20in%20the%20same%20site%3F%20Or%20a%20different%20site%20altogether%3F%3C%2FLINGO-BODY%3E
Highlighted
Occasional Contributor

Hi Team,

Need inputs in moving a copy of document along with its metadata columns and version history to a different document library using C# Console App (CSOM).

We are automating a scenario where we identify documents based on the document URL. Once identified , we need to move the document to a different document library along with the metadata columns and version history. 

I was successful in reading the columns and associated data for the document using the below code.

private static Dictionary<string, Dictionary<string, object>> getListData(ClientContext ctxObject,string libraryName)
        {
            var list = ctxObject.Web.Lists.GetByTitle(libraryName);

            FieldCollection fields = list.Fields;
            ctxObject.Load(fields);
            ctxObject.ExecuteQuery();

            var columns = new List<string> { "ID" };

            foreach(var f in fields)
            {
                if (f.InternalName.StartsWith("_") || f.InternalName.StartsWith("ows")) continue;
                if((f.FieldTypeKind == FieldType.Text)|| (f.FieldTypeKind== FieldType.DateTime) || (f.FieldTypeKind==FieldType.User))
                {
                    columns.Add(f.InternalName);
                }
            }

            List<Expression<Func<ListItemCollection, object>>> allIncludes = new List<Expression<Func<ListItemCollection, object>>>();

            foreach(var c in columns)
            {
                allIncludes.Add(items => items.Include(item => item[c]));
            }

            ListItemCollection listItems = list.GetItems(CamlQuery.CreateAllItemsQuery());
            ctxObject.Load(listItems, allIncludes.ToArray());
            ctxObject.ExecuteQuery();

            var sd = listItems.ToDictionary(k => k["Title"] as string, v => v.FieldValues);

            foreach(var i in sd.Keys)
            {
                foreach(var c in columns)
                {
                    Console.WriteLine("{0}:{1}", c, sd[i][c]);
                }
            }

            return sd;
        } 

 

But not sure how to create the above fetched columns and associated data along with the document in the new document library . Please suggest possible design patterns and any code artifacts that support this kind of scenario.

 

Thanks and Regards,

Sivapratap

6 Replies
Highlighted
Is the different library in the same site? Or a different site altogether?
Highlighted
Why not using the PnP to replicate your document library and the create the code required to move the documents from the source to the destination?
Highlighted

As Juan Carlos Mentioned PnP is your friend!

Highlighted
Highlighted
Hi,

Sorry to ask. I am not exactly clear on what PnP does. To be frank, after seeing your comment i started browsing about what exactly PnP is. Can you share artifacts on how to use PnP to replicate document library ?

Many Thanks,
Sivapratap.
Highlighted

You Could use Get template which is getting the whole site as xml.

then apply template to add everything to the site. 

 

in the xml you can remove the items you do not want to copy to the other site. it is really easy Vesa Juvonen and his team putted out a lot of howto's about pnp provisioning.