1

I have a list of URLs that are documents in a subfolder of a library.

When I go to update the metadata of a document in the library but not in a subfolder code works as expected.

But some documents in the list are in a subfolder. The URL has the fully qualified path to that document that includes the subfolder.

I can paste the url into a browser and open the document so I know it is correct, but when I get to the

context.Load(file, f.ListItemsAllFields); 
Context.ExecuteQuery();  -- Error Happens on URL of file in subfolder  

I am getting an error stating "File Not Found."

See Code... Again works if file is in root of Library just not when file is in a subfolder.

    /// <summary>
    /// Updates SharePoint MetaData for a specific document
    /// </summary>
    /// <param name="urlfilepath">The URL including file name of the file to be updated</param>
    /// <param name="values">this is a dictionary of propertyName and value to be updated.</param>
    private void UpdateMetaData(string urlfilepath, string library,Dictionary<string, string> mydictionary)
    {
        using (var context = new ClientContext(qsURLSite))
        {
            context.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
            var web = context.Web;

            // Get drop off library and edit all items without making changes
            context.Load(web, w => w.Lists);
            context.ExecuteQuery();

            List dropOffLibrary = web.Lists.GetByTitle(library);
            
            context.Load(dropOffLibrary, dl => dl.RootFolder.Files);
            context.ExecuteQuery();

            var file = dropOffLibrary.RootFolder.Files.GetByUrl(urlfilepath);
         
            context.Load(file, f => f.ListItemAllFields);
            context.ExecuteQuery();

            Microsoft.SharePoint.Client.ListItem newItem = file.ListItemAllFields;


            foreach (KeyValuePair<string, string> entry in mydictionary)
            {
                // entry.Key has to be in the property list of that document
                // the name is very specific
                try
                {
                    newItem[entry.Key] = entry.Value;
                }
                catch
                {
                    // Key was not found in list
                    // go to next key
                }
            }
            newItem.Update();
            //file.Update();
            context.Load(file);
            context.ExecuteQuery();

            context.Load(dropOffLibrary, dl => dl.RootFolder.Files);
            context.ExecuteQuery();
        }
    }
Fowl
  • 4,940
  • 2
  • 26
  • 43
Rog
  • 75
  • 2
  • 9

2 Answers2

2

Here is what I ended up getting to work.

eq is a record ID short for EQCode below in my code.

/// <summary>
      /// This procedure uploads documents to the Authorizations Library
      /// </summary>
      /// <param name="filename">File Being Uploaded</param>
      /// <param name="p">file in bytes</param>
      /// <param name="library">Library to upload to</param>
      /// <returns></returns>
        private string UploadToSharePoint(string filename, byte[] p,string library)  //p is path to file to load
        {
            string newUrl;
            string siteUrl = string.Empty; 


            siteUrl = qsURL + @"/repository/current/";
            // Calculate block size in bytes.
            int blockSize = fileChunkSizeInMB * 1024 * 1024;

            //Insert Credentials

             Microsoft.SharePoint.Client.ClientContext context = new Microsoft.SharePoint.Client.ClientContext(siteUrl);

            context.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
            Microsoft.SharePoint.Client.Web site = context.Web;

            if (context.HasPendingRequest)
                context.ExecuteQuery();

            try
            {

                //Get the required RootFolder
                string barRootFolderRelativeUrl = library;

                // Getting Folder List to see if EQCode Folder Exists  If not create it.

                string eq = txtEQCode.Text;
                FolderCollection folders = site.GetFolderByServerRelativeUrl(barRootFolderRelativeUrl).Folders;   //list.RootFolder.Folders;
                context.Load(folders, fl => fl.Include(ct => ct.Name)
                .Where(ct => ct.Name == eq));
                context.ExecuteQuery();

                if (folders.Count < 1)  // Create Folder because it does not exist on SharePoint Library
                {
                    folders.Add(eq);
                    context.ExecuteQuery();
                }

                Microsoft.SharePoint.Client.Folder barFolder = site.GetFolderByServerRelativeUrl(barRootFolderRelativeUrl);
                Microsoft.SharePoint.Client.Folder currentRunFolder = site.GetFolderByServerRelativeUrl(barRootFolderRelativeUrl + "/" + eq);

                //Microsoft.SharePoint.Client.FileCreationInformation newFile = new Microsoft.SharePoint.Client.FileCreationInformation { Content = p, Url = filename, Overwrite = true };
                //Microsoft.SharePoint.Client.File uploadFile = currentRunFolder.Files.Add(newFile);

                MemoryStream stream = new MemoryStream(p);

                FileCreationInformation flciNewFile = new FileCreationInformation();

                // This is the key difference for the first case – using ContentStream property
                flciNewFile.ContentStream = stream;
                flciNewFile.Url = System.IO.Path.GetFileName(fixInvalidCharactersInFileName(filename));
                flciNewFile.Overwrite = false;
                Microsoft.SharePoint.Client.File uploadFile = currentRunFolder.Files.Add(flciNewFile);

                currentRunFolder.Update();
                context.Load(uploadFile);
                context.ExecuteQuery();

                newUrl = siteUrl + barRootFolderRelativeUrl + "/" + filename;

                // Set document properties
                // Have to check out document to upldate properties.

                uploadFile.CheckOut();

                Microsoft.SharePoint.Client.ListItem listItem = uploadFile.ListItemAllFields;

                // Sets up ListItem fields based on Content Type 
                // as each content type has a different set of Required Fields.

                SetUpListItems(listItem, EQCode);

                listItem["Title"] = filename;
                listItem.Update();

                uploadFile.CheckIn("File Uploaded Manually added metadata", Microsoft.SharePoint.Client.CheckinType.MinorCheckIn);
                context.ExecuteQuery();

                //Return the URL of the new uploaded file
                return newUrl;
            }
            catch (Exception e)
            {
                Page.ClientScript.RegisterStartupScript(this.GetType(), "Error Uploading!", "alert('" + e.Message + "');", true);
                return "FALSE";
            }
        }
Rog
  • 75
  • 2
  • 9
0

list.RootFolder.Files.GetByUrl just return file in root folder, You could use web.GetFileByServerRelativeUrl instead.

Web web = context.Web;
                var list = web.Lists.GetByTitle("MyDoc3");
                var file1 =web.GetFileByServerRelativeUrl("/sites/lee/MyDoc3/ParentFolder/test2.docx");                
                var file2 = list.RootFolder.Files.GetByUrl("/sites/lee/MyDoc3/test.pptx");
                context.Load(file1);
                context.Load(file2);
                context.ExecuteQuery();
Lee
  • 5,305
  • 1
  • 6
  • 12