Поделиться через


Поддержка символов % и # в файлах и папках с использованием API ResourcePath

Поддержка символов % и # в файлах и папках в настоящее время развертывается в SharePoint Online. К сожалению, из-за существующих структур API и образцов вызовов работа с подобными именам файлов иногда может быть затруднительной. Вы можете найти дополнительную информацию по этому вопросу в нашем блоге для разработчиков.

В целом, новые API были добавлены в клиентскую объектную модель SharePoint Online для поддержки символов # и %.

Новый класс ResourcePath

В качестве подведения итогов, обратите внимание, что существующие API SharePoin на основе строк (например, SPFileCollection.GetByUrl) обрабатывают зашифрованные и незашифрованные URL-адреса путем автоматического предположения, что символы % и # в пути указывают на то, что URL-адрес был закодирован. Благодаря новому режиму поддержки символов % и # в файлах и папках такая автоматическая обработка теперь стала проблемой, так как она может привести к тому, что последующий код будет игнорировать или некорректно обрабатывать имена файлов с символами % и #.

Новый класс Microsoft.SharePoint.Client.ResourcePath был добавлен в API. Класс ResourcePath имеет фундаментальный характер для поддержки этих новых символов. Он предоставляет новый недвусмысленный способ обращения к элементу в SharePoint и OneDrive для бизнеса, поскольку он работает только с расшифрованными URL-адресами. Он заменяет на пути на основе строки для представления всего (абсолютного) или частичного (относительного) URL-адреса для семейства веб-сайтов, сайта, файла, папки или другого артефакта и OneDrive для бизнеса. Для корректной поддержки символов % и # в URL-адресах, необходимо использовать API на базе ResourcePath вместе с расшифрованными URL-адресами.

ResourcePath можно создать с помощью вызова статической функции ResourcePath.FromDecodedUrl(string). Передаваемое входное значение можно получить из объекта ResourcePath, вызвав свойство DecodedUrl.

Для существующих вызовов, которые выполняются с URL-адресом на основе строки, необходимо определить, были ли вызовы пути кода, ведущего к URL-адрес на основе строки, предоставлены с зашифрованным или расшифрованным URL-адресом, а также разрешают ли эти пути кода привязанные ссылки (т.е., дополнения #bookmark вверху URL-адрес файла).

Примечание.

Не используйте простую замену существующих методов использования API URL-адресов на базе строки с ResourcePath.FromDecodedUrl. Вам потребуется правильно определить URL-адрес и потенциально расшифровать URL-адреса, прежде чем использовать API ResourcePath.FromDecodedUrl(string).

В случаях, когда путь кода ведет к вызову API SharePoint на основе строки, используемому для расшифровки URL-адреса (например, «FY17 Report.docx»), вы можете просто заменить эти вызовы на ResourcePath.FromDecodedUrl(string) и эквивалентные методы ResourcePath, указанные ниже в этой статье.

Обратите внимание, что во многих случаях, когда вы считываете URL-адрес из SharePoint через API, ResourcePath также предоставляется, чтобы обеспечить большую однородность шаблонов кода, поэтому вы можете использовать ResourcePath вместо URL-адреса.

Обратите внимание на то, что это изменение распространяется также на вызовы SharePoint на основе REST. Ознакомьтесь со следующими сценариями, чтобы оценить примеры использования этих новых API в REST.

Новые API на основе ResourcePath, поддерживающие # и %

В следующей таблице показаны новые API, которые мы представили взамен существующих API для поддержки символов # и %. Мы перечислили старые и новые API рядом, чтобы у вас была возможность сравнить. Основные функциональные возможности этих API остаются без изменений, но изменилось то, в каком виде отображается расположение объекта.

Документацию по использованию новых API см. в статье Справка по API клиента .NET для SharePoint Online. Мы перечислили API .NET CSOM, но новые методы также доступны в эквивалентной форме в наших библиотеках JavaScript CSOM.

Сборка Microsoft.SharePoint.Client.dll

Тип Старый метод Новый метод
Microsoft.SharePoint.SPList AddItem(Microsoft.SharePoint.SPListItemCreationInformation) AddItemUsingPath(SPListItemCreationInformationUsingPath parameters)
Microsoft.SharePoint.SPFile MoveTo(System.String, Microsoft.SharePoint.SPMoveOperations) MoveToUsingPath (SPResourcePath newPath, SPMoveOperations moveOperations)
Microsoft.SharePoint.SPFile CopyTo(System.String, Boolean) CopyToUsingPath(SPResourcePath newPath, bool overwrite)
Microsoft.SharePoint.SPFileCollection GetByUrl(System.String) GetByPath(SPResourcePath)
Microsoft.SharePoint.SPFileCollection Add(System.String, Microsoft.SharePoint.SPTemplateFileType) AddUsingPath(SPResourcePath, SPFileCollectionAddWithTemplateParameters)
Microsoft.SharePoint.SPFolder MoveTo(System.String) MoveToUsingPath(SPResourcePath newPath)
Microsoft.SharePoint.SPFolder AddSubFolder(System.String) AddSubFolderUsingPath(SPResourcePath leafPath)
Microsoft.SharePoint.SPFolderCollection GetByUrl(System.String) GetByPath(SPResourcePath path)
Microsoft.SharePoint.SPFolderCollection Add(System.String) AddUsingPath(SPResourcePath path, SPFolderCreationInformation parameters)
AddWithOverwrite(string url, bool overwrite)
Microsoft.SharePoint.SPRemoteWeb GetFileByServerRelativeUrl(System.String) GetFileByServerRelativePath(SPResourcePath path)
Microsoft.SharePoint.SPWeb GetList(System.String) GetListUsingPath(SPResourcePath)
Microsoft.SharePoint.SPWeb GetListItem(System.String) GetListItemUsingPath(SPResourcePath)

Указанные ниже объекты CSOM возвращают свойства ResourcePath, которые могут использоваться в этих API. Несмотря на то, что старое свойство также возвращает расшифрованные URL-адреса, новое свойство ResourcePath предназначено для обеспечения большего удобства, простоты и четкости при вызове этих API. Единственное исключение – это свойство SPFolder.WelcomePage, которое ранее возвращало зашифрованный и расшифрованный URL-адреса; теперь это однозначно возвращается через свойство WelcomePagePath.


Тип Старое свойство Новое свойство
Microsoft.SharePoint.SPList DefaultViewUrl DefaultViewPath
Microsoft.SharePoint.SPList DefaultEditFormUrl DefaultEditFormPath
Microsoft.SharePoint.SPList DefaultNewFormUrl DefaultNewFormPath
Microsoft.SharePoint.SPList DefaultDisplayFormUrl DefaultDisplayFormPath
Microsoft.SharePoint.SPAttachment ServerRelativeUrl ServerRelativePath
Microsoft.SharePoint.SPFile ServerRelativeUrl ServerRelativePath
Microsoft.SharePoint.SPFolder ServerRelativeUrl ServerRelativePath
Microsoft.SharePoint.SPFolder WelcomePage WelcomePagePath/ WelcomePageParameters
Microsoft.SharePoint.SPView ServerRelativeUrl ServerRelativePath
Microsoft.SharePoint.SPDocumentLibraryInformation ServerRelativeUrl ServerRelativePath

Существующие API, которые не страдают от двоякого толкования формата URL-адреса и поддерживают символы # и %

Представленные ниже API принимают только правильно зашифрованные URL-адреса в качестве входных данных. Они также поддерживают URL-адреса в процессе шифрования, при условии, что URL-адрес можно использовать без какой-либо неоднозначности. Другими словами, как минимум символы # и % в пути URL-адрес должны быть зашифрованы. Эти API будут продолжать работать существующим образом. # в URL-адресе принимается за фрагмент разделитель, а не за часть пути URL-адреса.

Тип Старое свойство
Microsoft.SharePoint.SPWeb GetFileByUrl(System.String)
Microsoft.SharePoint.SPWeb GetFileByWOPIFrameUrl(System.String)
Microsoft.SharePoint.SPWeb GetFileByLinkingUrl(System.String)

Указанные ниже свойства C# свойства добавлены для возврата System.Uri с недвусмысленной кодировкой для работы с API выше. Более ранние версии API, представленных ниже, возвращали раскодированные URL-адреса, а так как они никогда не содержат символы # и %, URL-адрес не имел двоякое толкование. В дальнейшем мы не хотели бы разрывать поведение при расшифровке для более ранних версий для кодирования % и # символов в пути. На основании этого были созданы новые API.

Тип Старое свойство Новое свойство
Microsoft.SharePoint.SPFile LinkingUrl LinkingUri
Microsoft.SharePoint.SPFile ServerRedirectedEmbedUrl ServerRedirectedEmbedUri

Пример кода

Сценарии CSOM

Добавление файла в папку (.net)

 ClientContext context = new ClientContext("http://site");
 Web web = context.Web;
 // Get the parent folder
 ResourcePath folderPath = ResourcePath.FromDecodedUrl("/Shared Documents");
 Folder parentFolder = web.GetFolderByServerRelativePath(folderPath);
 
 // Create the parameters used to add a file
 ResourcePath filePath = ResourcePath.FromDecodedUrl("/Shared Documents/hello world.txt");
 byte[] fileContent = System.Text.Encoding.UTF8.GetBytes("sample file content");
 FileCollectionAddParameters fileAddParameters = new FileCollectionAddParameters();
 fileAddParameters.Overwrite = true;
 using (MemoryStream contentStream = new MemoryStream(fileContent))
 {
  // Add a file
  Microsoft.SharePoint.Client.File addedFile = parentFolder.Files.AddUsingPath(filePath, fileAddParameters, contentStream);
 
  // Select properties of added file to inspect
  context.Load(addedFile, f => f.UniqueId, f1 => f1.ServerRelativePath);
 
  // Perform the actual operation
  context.ExecuteQuery();
 
  // Print the results
  Console.WriteLine(
   "Added File [UniqueId:{0}] [ServerRelativePath:{1}]",
   addedFile.UniqueId,
   addedFile.ServerRelativePath.DecodedUrl);
 }


Добавление вложенной папки в папку (.net)

  ClientContext context = new ClientContext("http://site");
  Web web = context.Web;
  // Get the parent folder
  ResourcePath folderPath = ResourcePath.FromDecodedUrl("Shared Documents");
  Folder parentFolder = web.GetFolderByServerRelativePath(folderPath);
 
  // Create the parameters used to add a folder
  ResourcePath subFolderPath = ResourcePath.FromDecodedUrl("Shared Documents/sub folder");
  FolderCollectionAddParameters folderAddParameters = new FolderCollectionAddParameters();
  folderAddParameters.Overwrite = true;
 
  // Add a sub folder
  Folder addedFolder = parentFolder.Folders.AddUsingPath(subFolderPath, folderAddParameters);
 
  // Select properties of added file to inspect
  context.Load(addedFolder, f => f.UniqueId, f1 => f1.ServerRelativePath);
 
  // Perform the actual operation
  context.ExecuteQuery();
 
  // Print the results
  Console.WriteLine(
    "Added Folder [UniqueId:{0}] [ServerRelativePath:{1}]",
    addedFolder.UniqueId,
    addedFolder.ServerRelativePath.DecodedUrl);

Получение файла в Интернете (.net)

  ClientContext context = new ClientContext("http://site");
  Web web = context.Web;
  // Get the file
  ResourcePath filePath = ResourcePath.FromDecodedUrl("/Shared Documents/hello world.txt");
  File file = web.GetFileByServerRelativePath(filePath);
 
  // Select properties of the file
  context.Load(file, f => f.UniqueId, f1 => f1.ServerRelativePath);
 
  // Perform the actual operation
  context.ExecuteQuery();
 
  // Print the results
  Console.WriteLine(
    "File Properties [UniqueId:{0}] [ServerRelativePath:{1}]",
    file.UniqueId,
    file.ServerRelativePath.DecodedUrl);

Сценарии REST

Получение папок

url: http://site url/_api/web/GetFolderByServerRelativePath(decodedUrl='library name/folder name')
method: GET
headers:
  Authorization: "Bearer " + accessToken
  accept: "application/json;odata=verbose" or "application/atom+xml"


Создание папок

url: http://site url/_api/web/Folders/AddUsingPath(decodedurl='/document library relative url/folder name')
method: POST
headers:
  Authorization: "Bearer " + accessToken
  X-RequestDigest: form digest value
  accept: "application/json;odata=verbose"
  content-type: "application/json;odata=verbose"
 

Получение файлов

url: http://site url/_api/web/GetFileByServerRelativePath(decodedUrl='folder name/file name')
method: GET
Headers:
  Authorization: "Bearer " + accessToken
  accept: "application/json;odata=verbose" or "application/atom+xml"


Добавление файлов

url: http://site url/_api/web/GetFolderByServerRelativePath(decodedUrl='folder name')/Files/AddStubUsingPath(decodedurl='testfile.txt')
methods: POST
Headers:
  Authorization: "Bearer " + accessToken
  X-RequestDigest: form digest value
  accept: "application/json;odata=verbose"
  content-type: "application/json;odata=verbose"
  Content-Length: length
 

См. также