Search code examples
c#asp.netsharepoint-2013csomsharepoint-clientobject

CSOM Update File Document MetaData in a Subfolder of a library. Getting Error File Not Found


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

Solution

  • 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();