Partager via


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
 

Voir aussi