Поддержка символов % и # в файлах и папках с использованием 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