none
Programmatically move file with SharePoint 2010 Managed Client Object model RRS feed

  • Question

  • Hi guys.

    I've written the following method to move a file from one document library to another:

     

          // set up client context for source doc library
          ClientContext client = new ClientContext(spURL + "/Districts/" + pre_district);
          List hcList = client.Web.Lists.GetByTitle("Health Check Surveys");
    
          // query existing doc library to find file to move
          CamlQuery hcQuery = new CamlQuery();
          hcQuery.ViewXml = "<Where><Eq><FieldRef Name=\"_x0039_2acd126_x002d_d5ae_x002d_450f_x002d_8a2a_x002d_da97a28d42c3\" /><Value Type=\"String\">" + account + "</Value></Eq></Where>";
          ListItemCollection hcItems = hcList.GetItems(hcQuery);
          client.Load(hcList);
          client.Load(hcItems);
          client.ExecuteQuery();
    
          if (hcItems.Count > 0)
          {
            // set up new destination for destination doc library
            string destinationURL = spURL + "/Districts/" + post_district + "/Health Checks/";
    
            foreach (ListItem item in hcItems)
            {
              File myFile = item.File;
              client.Load(myFile);
              client.ExecuteQuery();
    
              // move file to new library
              destinationURL = destinationURL + myFile.Name;
              myFile.MoveTo(destinationURL, MoveOperations.Overwrite);
              item.Update();
              client.ExecuteQuery();
            }
          }
    

    when i call the last ExecuteQuery() method, I get the following exception:

    [Microsoft.SharePoint.Client.ServerException] = {"Value does not fall within the expected range."}

    StackTrace = "   at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream)\r\n   at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()\r\n   at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb)...

    Friday, August 19, 2011 4:56 PM

Answers

  • I think your bringing back folders in your ListItemCollection. The following code is working for me. It uses the lamda to include properties to bring back properties you need to work with.You then can check to see if the File property is null, and in the case of a folder it will be.

    public static void MoveFiles()
    {
           ClientContext clientContext = new ClientContext("http://basesmc2008");
           List list = clientContext.Web.Lists.GetByTitle("tester2");
    
           ListItemCollection listItems = list.GetItems(CamlQuery.CreateAllItemsQuery());
           clientContext.Load(listItems, items => items.Include
                           (item => item["Author"],
                           item => item["Editor"],
                           item => item["EncodedAbsUrl"],
                           item => item["Modified"],
                           item =>item.File));
    
           clientContext.ExecuteQuery();
    
           if (listItems.Count > 0)
           {
             // set up new destination for destination doc library
             string destinationLib = "/tester3/";
    
             foreach (ListItem item in listItems)
             {
               if (!item.File.ServerObjectIsNull.Value)
               {
                 destinationLib = destinationLib + item.File.Name;
    
                 // move file to new library
                 item.File.MoveTo(destinationLib, MoveOperations.Overwrite);
                 clientContext.ExecuteQuery();
               }
             }
           }
    }
    

     


    Blog | SharePoint Field Notes Dev Tool | ClassMaster
    • Proposed as answer by Shimin Huang Thursday, August 25, 2011 9:09 AM
    • Marked as answer by Shimin Huang Friday, August 26, 2011 8:42 AM
    Wednesday, August 24, 2011 12:28 AM

All replies

  • Which ExecuteQuery are you getting the error on? It could be a non-existent destination URL.
    Blog | SharePoint Field Notes Dev Tool | ClassMaster
    Friday, August 19, 2011 5:15 PM
  • Thanks for the reply Steve.  I am getting an error with the following piece of code: 

         // move file to new library
         destinationURL = destinationURL + myFile.Name;
         myFile.MoveTo(destinationURL, MoveOperations.Overwrite);
         item.Update();
         client.ExecuteQuery();
    
    

    I validated that I have an existing destinationURL.  I should say, though, that the url is in a different site outside of this ClientContext object that was instantiated.  Do you think that would make a difference?  I also attempted to try a relative and absolute URL in my destinationURL value.  Both of those produced the same error.

    Thanks for your help!


    Sam www.samporras.com
    Friday, August 19, 2011 7:01 PM
  • The destination Url must be in the same site collection as the client context which it looks like it is. It could be the item.Update call. Since you have moved the item, it is no longer there, so don't update it.
    Blog | SharePoint Field Notes Dev Tool | ClassMaster
    • Proposed as answer by Sven W Saturday, August 20, 2011 9:15 PM
    Saturday, August 20, 2011 3:29 AM
  • Thanks Steve. I thought either of those scenarios would be causing the error, but it turns out they are not.  I confirmed that the destination URL is correct (doc library exists) and is in the same site collection.  I also removed the item.Update() method and tried making the destinationURL an both an absolute and relative URL (see code below).  I guess i should take a step back and ask myself if this is this the right approach to move a file across document libraries using the managed client object model?  Is there a better approach??
          if (hcItems.Count > 0)
          {
            // set up new destination for destination doc library
            string destinationLib = "/sales/Districts/" + post_district + "/Health Check Surveys/";
            
    
            foreach (ListItem item in hcItems)
            {
              File myFile = item.File;
              client.Load(myFile);
              client.ExecuteQuery();
    
              // string sourceLib = myFile.ServerRelativeUrl;
              destinationLib = destinationLib + myFile.Name;
    
              // move file to new library
              myFile.MoveTo(destinationLib, MoveOperations.Overwrite);
              client.ExecuteQuery();
            }
          }
    

    www.samporras.com
    Tuesday, August 23, 2011 7:45 PM
  • I think your bringing back folders in your ListItemCollection. The following code is working for me. It uses the lamda to include properties to bring back properties you need to work with.You then can check to see if the File property is null, and in the case of a folder it will be.

    public static void MoveFiles()
    {
           ClientContext clientContext = new ClientContext("http://basesmc2008");
           List list = clientContext.Web.Lists.GetByTitle("tester2");
    
           ListItemCollection listItems = list.GetItems(CamlQuery.CreateAllItemsQuery());
           clientContext.Load(listItems, items => items.Include
                           (item => item["Author"],
                           item => item["Editor"],
                           item => item["EncodedAbsUrl"],
                           item => item["Modified"],
                           item =>item.File));
    
           clientContext.ExecuteQuery();
    
           if (listItems.Count > 0)
           {
             // set up new destination for destination doc library
             string destinationLib = "/tester3/";
    
             foreach (ListItem item in listItems)
             {
               if (!item.File.ServerObjectIsNull.Value)
               {
                 destinationLib = destinationLib + item.File.Name;
    
                 // move file to new library
                 item.File.MoveTo(destinationLib, MoveOperations.Overwrite);
                 clientContext.ExecuteQuery();
               }
             }
           }
    }
    

     


    Blog | SharePoint Field Notes Dev Tool | ClassMaster
    • Proposed as answer by Shimin Huang Thursday, August 25, 2011 9:09 AM
    • Marked as answer by Shimin Huang Friday, August 26, 2011 8:42 AM
    Wednesday, August 24, 2011 12:28 AM
  • Thanks for all your help Steve.  I think I found the issue.  I think there's a limitation in using the File.MoveTo() that constrains you from moving a file from one sharepoint site to another.  I was attempting to move the file from

    http://sharepoint/siteA/list

    to

    http://sharepoint/siteB/list

    The code you provided above works because you are moving the file between two document libraries within the same site/web (whatever you call it :)).  I ended up using the File.SaveBinaryDirect() method and then deleting the item object in my code.  It looks something like this:

        private static void MoveFiles(string pre_district, string post_district, string spURL)
        {
          ClientContext myClient = new ClientContext(spURL);
    
          Site collection = myClient.Site;
          myClient.Load(collection, cols => cols.ServerRelativeUrl);
          myClient.ExecuteQuery();
    
          Web sWeb = collection.OpenWeb(collection.ServerRelativeUrl + "/Districts/" + pre_district);
          myClient.Load(sWeb, w => w.Lists);
          myClient.ExecuteQuery();
    
          List hcsList = sWeb.Lists.GetByTitle("Health Check Surveys");
          ListItemCollection hcItems = hcsList.GetItems(CamlQuery.CreateAllItemsQuery());
    
          myClient.Load(hcsList);
          myClient.Load(hcItems, items => items.Include(item => item["Author"], item => item["Editor"], item => item["EncodedAbsUrl"], item => item["Modified"], item => item.File));
          myClient.ExecuteQuery();
    
          if (hcItems.Count > 0)
          {
            // set up new destination for destination doc library
            string destinationLib = "/sales/Districts/" + post_district + "/Health Check Surveys/";
    
            foreach (ListItem item in hcItems)
            {
              if (!item.File.ServerObjectIsNull.Value)
              {
                // string sourceLib = myFile.ServerRelativeUrl;
                destinationLib = destinationLib + item.File.Name;
    
                File.SaveBinaryDirect(myClient, destinationLib, File.OpenBinaryDirect(myClient, item.File.ServerRelativeUrl).Stream, true);
    
                item.DeleteObject();
              }
            }
    
            myClient.ExecuteQuery();
          }
        }
    

     


    www.samporras.com
    Thursday, August 25, 2011 9:28 PM
  • I am able to successfully use

     item.File.CopyTo(destinationLib, true);but when I use

     item.File.MoveTo(destinationLib, MoveOperations.Overwrite);

    I receive an error that MoveOperations is undefined. Is there some sort of client side reference I need?

     

    Thanks

    Ed Santosusso


    Ed Santosusso
    Sunday, November 27, 2011 9:27 PM