0

I have about 136K files I need to download from my SharePoint site so I can create an MD5 has for the files and record the has values in a local database. I am using the following code below to grab the list of files:

 public static List<SP.ListItem> GetAllDocumentsInaLibrary()
    {
        List<SP.ListItem> items = new List<SP.ListItem>();
        string siteURL = @"[URL to SharePoint]";
        using (var ctx = new SP.ClientContext(siteURL))
        {
            ctx.Load(ctx.Web, a => a.Lists);
            ctx.ExecuteQuery();
            int i = 0;
            SP.List list = ctx.Web.Lists.GetByTitle("ArchivedData");
            SP.ListItemCollectionPosition position = null;
            int rowLimit = 100;
            var camlQuery = new SP.CamlQuery();
            camlQuery.ViewXml = @"<View Scope='RecursiveAll'>
                                  <Query>
                                    <OrderBy Override='TRUE'><FieldRef Name='ID'/></OrderBy>
                                  </Query>
                                  <ViewFields>
                                        <FieldRef Name='Title'/><FieldRef Name='ID' />
                                  </ViewFields>
                                  <RowLimit Page='TRUE'>" + rowLimit + "</RowLimit></View>";
            do
            {
                SP.ListItemCollection listItems = null;
                camlQuery.ListItemCollectionPosition = position;
                listItems = list.GetItems(camlQuery);
                ctx.Load(listItems);
                ctx.ExecuteQuery();
                i += 100;
                position = listItems.ListItemCollectionPosition;
                items.AddRange(listItems.ToList());
                Console.WriteLine(i);
            }
            while (position != null);
        }
        return items;
    }

Here is the calling line for this code:

List<SP.ListItem> item = GetAllDocumentsInaLibrary();

This works just fine. Now I want to iterate this list and download the files, to local location so I can create the MD5 hash of the file, and this is where I am stuck. I used this code below to pull 10 files at a time and it worked, but now, I want to iterate the whole list generated from the GetAllDocumentsInaLibrary method to do this.

 SP.ClientContext ctx = new SP.ClientContext(url);
        SP.Web oWebSite = ctx.Web;
        SP.List list = oWebSite.Lists.GetByTitle("ArchivedData");


            foreach (SP.ListItem listitem in item)
            {
                ctx.Load(listitem, i => i.File);
                ctx.ExecuteQuery();
                var fileRef = listitem.File.ServerRelativeUrl;
                var fileInfo = SP.File.OpenBinaryDirect(ctx, fileRef);
                var fileName = @"c:\downloads\" + (string.IsNullOrEmpty(listitem.File.Title) ? listitem.File.Name : listitem.File.Title);
                using (var fileStream = File.Create(fileName))
                {
                    fileInfo.Stream.CopyTo(fileStream);
                }
            }

When I try to do this, I get an error on the ctx.Load(Listitem, i => i.File) line:

Additional information: The object is used in the context different from the one associated with the object.

Can anyone help me on this?

Thanks.

2
  • It is as the error says. The generic list of items (item) you generated refer to a different context than the one in the foreach (SP.ListItem listitem in item). Hence the error. You need to have the same context for both. That said, you should probably use a parallel.foreach loop if you have that many files. Refer to stackoverflow.com/questions/19981744/…
    – Akhoy
    Commented May 17, 2018 at 16:51
  • Thanks. I think I got around this. I am wrapping this loop into parallel.foreach, but I am not seeing much of an increase at all. Still working through that.
    – john
    Commented May 17, 2018 at 17:56

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.