Prise en charge des caractères % et # dans les fichiers et dossiers avec l’API ResourcePath
Prise en charge des caractères % et # dans les fichiers et dossiers déployés dans SharePoint Online. Malheureusement, en raison des structures et modèles d’appel d’API existants, ces noms de fichier peuvent parfois devenir ambigus. Vous trouverez davantage d’éléments à ce sujet sur notre blog du développeur.
En résumé, de nouvelles API ont été ajoutées à la surface du modèle objet client (CSOM) SharePoint Online pour la prise en charge des caractères # et %.
Nouvelle classe ResourcePath
Pour récapituler, notez que les API SharePoint basées sur des chaînes existantes (telles que SPFileCollection.GetByUrl) gèrent les URL codées et décodées en supposant automatiquement que la présence de caractères % et # dans un chemin d’accès implique que l’URL a été codée. Avec la nouvelle prise en charge des caractères % et # dans les fichiers et dossiers, ce traitement automatique est désormais problématique, car il peut avoir pour effet que le code en aval ignore ou gère mal les noms de fichiers contenant des caractères % et #.
Une nouvelle classe, Microsoft.SharePoint.Client.ResourcePath
, a été ajoutée à l’API. La classe ResourcePath est fondamentale pour la prise en charge de ces nouveaux caractères. Elle offre un nouveau moyen non ambigu d’adresser un élément dans SharePoint et OneDrive Entreprise, supposant que les URL sont décodées et ne fonctionnent qu’avec de telles URL. Elle remplace les chemins d’accès basés sur chaîne pour représenter une URL complète (absolue) ou partielle (relative) d’une collection de sites, d’un site, d’un fichier, d’un dossier ou de tout autre artefact et OneDrive Entreprise. Pour prendre en charge correctement les caractères % et # au sein des URL, vous devez utiliser les API basées sur ResourcePath avec des URL décodées.
Il est possible de construire ResourcePath simplement en appelant une fonction statique ResourcePath.FromDecodedUrl(string)
. La valeur d’entrée transmise est accessible à partir de l’objet ResourcePath en appelant la propriété DecodedUrl.
Pour les appels existants prenant une URL basée sur une chaîne, vous devez déterminer si le chemin de code menant aux appels d’URL basés sur une chaîne a été fourni avec des URL codées ou décodées, et si ce chemin de code autorisait également des liens d’ancrage (c’est-à-dire des ajouts #bookmark à l’URL du fichier).
Remarque
Ne vous contentez pas de simplement rechercher et remplacer des utilisations existantes d’API d’URL basées sur une chaîne avec ResourcePath.FromDecodedUrl
. Vous devez déterminer correctement les URL et potentiellement les décoder avant d’utiliser l’API ResourcePath.FromDecodedUrl(string)
.
Dans les cas où un chemin de code menant à un appel d’API SharePoint basée sur une chaîne utilisait des URL décodées (par exemple, « FY17 Report.docx »), vous pouvez simplement remplacer ces appels par ResourcePath.FromDecodedUrl(string)
et des méthodes ResourcePath équivalentes répertoriées plus loin dans cet article.
Notez que, dans de nombreux cas où vous lisez l’URL à partir de SharePoint via des API, la valeur ResourcePath est également fournie pour rendre ces modèles de code plus cohérents afin que vous puissiez utiliser la valeur ResourcePath plutôt que l’URL.
Notez aussi que cette modification s’applique également aux appels basés sur REST SharePoint. Examinez les scénarios suivants pour voir des exemples de ces nouvelles API dans REST.
Nouvelles API basées sur ResourcePath prenant en charge les caractères # et %
Le tableau suivant présente les nouvelles API que nous avons introduites pour remplacer les API existantes afin de prendre en charge les caractères # et %. Nous répertorié l’ancienne et la nouvelle API côte à côte pour faciliter la comparaison. Les principales fonctionnalités de ces API ne changent pas, mais la manière de représenter l’emplacement de l’élément change.
Pour accéder à une documentation concernant les nouvelles API, voir Référence d’API client .NET pour SharePoint Online. Nous avons répertorié les API CSOM .NET, mais les nouvelles méthodes sont également disponibles sous une forme équivalente dans nos bibliothèques CSOM JavaScript.
Assembly Microsoft.SharePoint.Client.dll
Type | Ancienne méthode | Nouvelle méthode |
---|---|---|
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) |
Les objets CSOM suivants renvoient des propriétés ResourcePath utilisables dans ces API. Bien que l’ancienne propriété renvoie également des URL décodées, la nouvelle propriété ResourcePath est fournie pour plus de commodité, de simplicité et de clarté dans l’appel de ces API. L’unique exception est la propriété SPFolder.WelcomePage qui renvoyait précédemment des URL tant codées que non codées. Les URL sont désormais renvoyées sans ambiguïté via la propriété WelcomePagePath.
Type | Ancienne propriété | Nouvelle propriété |
---|---|---|
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 |
Les API existantes qui ne sont pas ambiguës sur le plan du format de l’URL et peuvent prendre en charge les caractères # et %
Les API suivantes n’acceptent comme entrée que des URL correctement codées. Elles prennent également en charge les URL sous-codées tant que celles-ci sont utilisables sans ambiguïté. Autrement dit, au moins les caractères # ou % dans le chemin d’accès de l’URL doivent être codés %. Ces API continueront de fonctionner comme d’habitude. #
dans l’URL est traité comme un séparateur de fragment, pas comme une partie du chemin de l’URL.
Type | Ancienne propriété |
---|---|
Microsoft.SharePoint.SPWeb | GetFileByUrl(System.String) |
Microsoft.SharePoint.SPWeb | GetFileByWOPIFrameUrl(System.String) |
Microsoft.SharePoint.SPWeb | GetFileByLinkingUrl(System.String) |
Les propriétés C# suivantes sont ajoutées pour renvoyer System.Uri avec un codage non ambigu à utiliser avec les API ci-dessus. La variante plus ancienne des API suivantes renvoyait des URL décodées et, comme elles ne contenaient jamais de caractère # ou %, l’URL n’était pas ambiguë. À l’avenir, nous ne voulions pas perturber le comportement décodé des variantes plus anciennes pour coder les caractères % et # dans le chemin. C’est pourquoi de nouvelles API ont été créées.
Type | Ancienne propriété | Nouvelle propriété |
---|---|---|
Microsoft.SharePoint.SPFile | LinkingUrl | LinkingUri |
Microsoft.SharePoint.SPFile | ServerRedirectedEmbedUrl | ServerRedirectedEmbedUri |
Exemple de code
Scénarios CSOM
Ajouter un fichier à un dossier (.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);
}
Ajouter un sous-dossier à un dossier (.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);
Obtenir un fichier dans le web (.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);
Scénarios REST
Obtenir les dossiers
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"
Créer un dossier
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"
Obtenir les fichiers
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"
Ajouter des fichiers
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