C# SharePoint CSOM изменяет свойства файла после загрузки

Я искал и нашел несколько примеров того, как это сделать, но я не могу заставить их работать - ну, часть этого не работает. Я могу выполнить загрузку файла, но следующая попытка изменить свойства не удалась.

Я пытаюсь загрузить файл из полезной нагрузки base64 - эта часть работает, но когда я впоследствии пытаюсь отредактировать свойства (настраиваемый столбец), связанные с файлом, код дает сбой.

Вот код (упрощенный для удобства чтения): (обратите внимание, что props — это набор пользовательских объектов (FileProperty) с именем и атрибутом value).

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

Этот код выдает исключение в той части, где я пытаюсь обновить свойства. Сообщение: Файл не найден.

Может ли кто-нибудь сказать мне, что не так с этим примером, или привести другой пример того, как это сделать?

Кроме того, вопрос - есть ли способ обратиться к файлу по уникальному идентификатору, который будет одинаковым независимо от того, где на сервере SharePoint файл находится или куда он перемещен?

Я надеюсь, что кто-то может мне помочь - спасибо :)


person Aidal    schedule 17.09.2020    source источник
comment
Я также пытался добавить context.ExecuteQuery(); в конце концов, но это не имеет значения.   -  person Aidal    schedule 17.09.2020
comment
Также для уточнения - файл загружается и виден в браузере при просмотре локации. Это только попытка изменить свойства, которая терпит неудачу из-за того, что файл не найден.   -  person Aidal    schedule 21.09.2020


Ответы (2)


Хорошо, я нашел решение своей проблемы. Я не знаю, почему это работает лучше, это просто так. Насколько я знаю, я делаю то же самое, только по-другому — может быть, кто-то, кто знает о SharePoint больше, чем я (что немного), может объяснить, почему это работает, а первый опубликованный мной пример — нет. .

Перед показанным кодом я гарантирую, что ‹site_url› не заканчивается на / и что ‹library_name› не начинается и не заканчивается на / и что ‹file_name› не начинается и не заканчивается на /. С помощью приведенного ниже кода я могу загрузить файл и обновить свойства, в моем случае я изменил заголовок и пользовательский столбец CustCulomnA, и это работает.

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();
person Aidal    schedule 21.09.2020
comment
, Да, структура URL-адреса файла должна быть siteurl/libraryname/filename, и я видел фрагмент кода выше, newFile должно быть действительным сейчас. Рад это слышать, и теперь вы можете принять это как ответ, чтобы он также мог помочь другим на форуме :-) - person Jerry; 22.09.2020

Убедитесь, что в этом случае относительный URL-адрес файлового сервера действителен.

Например, если полный URL-адрес:

https://zheguo.sharepoint.com/sites/test/Shared%20Documents/test.jpg

Тогда относительный URL должен быть

/sites/test/Shared%20Documents/test.jpg

И вы также можете использовать метод GetFileByUrl, передав полный URL-адрес файла следующим образом:

               clientContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);
                Web web = clientContext.Web;
                clientContext.Load(web);
                clientContext.ExecuteQuery();
                File file = web.GetFileByUrl("https://zheguo.sharepoint.com/sites/test/Shared%20Documents/test.jpg");
                clientContext.Load(file);
                clientContext.ExecuteQuery();
                file.CheckOut();
                ListItem item = file.ListItemAllFields;
                item["Title"] = "Test";
                item.Update();
                file.CheckIn(string.Empty, CheckinType.OverwriteCheckIn);
                clientContext.ExecuteQuery();
            }
person Jerry    schedule 18.09.2020
comment
Мой относительный URL-адрес правильный - он используется в коде для создания файла, и я пишу его только для проверки правильности. Но я попытаюсь использовать подход с полным путем и посмотрю, будет ли это иметь значение. - person Aidal; 21.09.2020
comment
ОК, я попробовал этот подход сейчас, и результат тот же, файл загружается нормально, но после этого файл не найден. Проблема в том, что я использую тот же ClientContext для извлечения файла для редактирования, который использовался для его создания чуть выше в коде? - Я не создаю новый ClientContext, а повторно использую тот, который у меня уже есть. - person Aidal; 21.09.2020
comment
@Aidal, ClientContext для загрузки файла и получения файла должен быть одинаковым. - person Jerry; 22.09.2020