sharepointsharepoint-onlinecsomfile-properties

C# SharePoint CSOM change file properties after upload


I have searched and found several examples of how to do this, but I can't make them work - well part of it doesn't work. I can perform the file upload, but the following attempt to change properties fail.

I'm attempting to upload a file from a base64 payload - this part works - but when I afterwards attempt to edit the properties (custom column) associated with the file, the code fails.

Here is the code (simplified for readability): (note that props is a collection of custom objects (FileProperty) with a name and a value attribute).

using (ClientContext context = new ClientContext("<sharepoint_server_url>"))
                {
                    context.Credentials = new SharePointOnlineCredentials(<usr>,<secure_pwd>);

                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream(Convert.FromBase64String(<base64_content>)))
                    {
                        File.SaveBinaryDirect(context, <relative_path>, ms, true);
                    }

                    // file is uploaded - so far so good!
                    // attempt to edit properties of the file.

                    if (props != null)
                    {
                        if (props.Count > 0)
                        {
                            File newFile = context.Web.GetFileByServerRelativeUrl(<relative_path>);

                            context.Load(newFile);
                            context.ExecuteQuery();

                            newFile.CheckOut();

                            ListItem item = newFile.ListItemAllFields;

                            foreach (FileProperty fp in props)
                            {
                                item[fp.name] = fp.value;                                
                            }

                            item.Update();
                            newFile.CheckIn(string.Empty, CheckinType.OverwriteCheckIn);
                        }
                    }
                }

This code throws an exception in the part where I try to update the properties. Message: The file was not found.

Can anyone tell me what is wrong with this example or provide another example on how to do this?

Also, a question - is there a way to address a file by a unique ID which is the same regardless of where in the SharePoint server the file is located or moved to?

I hope someone can help me out - thanks :)


Solution

  • Ok, I found a solution to my problem. I don't know why this works better, it just does. For all I know, I'm doing the exact same thing, just in another way - maybe someone else who knows more about SharePoint than me (which isn't much) can explain why this works while the first example I posted doesn't.

    Previous to the code shown, I ensure that <site_url> doesn't end with "/" and that <library_name> doesn't start or end with "/" and that <file_name> doesn't start or end with "/". With the code below I can uplaod a file and update properties, in my case i changed "Title" and a custom column "CustCulomnA" and it workes.

    using (ClientContext context = new ClientContext(<site_url>))
                    {
                        context.Credentials = new SharePointOnlineCredentials(<usr>, <secure_pwd>);
    
                        FileCreationInformation fci = new FileCreationInformation()
                        {
                            Url = <file_name>,
                            Content = Convert.FromBase64String(<base64_content>),
                            Overwrite = true
                        };
    
                        Web web = context.Web;
                        List lib = web.Lists.GetByTitle(<library_name>);
                        lib.RootFolder.Files.Add(fci);
                        context.ExecuteQuery();
    
                        response.message = "uploaded";
    
                        if (props != null)
                        {
                            if (props.Count > 0)
                            {
                                File newFile = context.Web.GetFileByUrl(<site_url> +"/"+ <library_name> + "/" + <file_name>);
                                context.Load(newFile);
                                context.ExecuteQuery();
                                newFile.CheckOut();
    
                                ListItem item = newFile.ListItemAllFields;
    
                                foreach (FileProperty fp in props)
                                {
                                    item[fp.name] = fp.value;
                                }
    
                                item.Update();
    
                                newFile.CheckIn(string.Empty, CheckinType.OverwriteCheckIn);
                                context.ExecuteQuery();