Utiliser les données de colonne de fichier

Les colonnes de fichier sont différentes des autres colonnes du système qui peuvent stocker des données binaires, car vous ne pouvez pas définir directement les valeurs dans une opération de création ou de mise à jour, ou récupérer les données de fichier avec l’enregistrement. Vous devez utiliser les méthodes décrites dans cet article pour créer, récupérer, mettre à jour ou supprimer des données binaires pour les colonnes de fichier.

Il existe plusieurs façons d’utiliser les données de colonne de fichier avec l’API Web. Toutes les méthodes sont prises en charge de la même manière. Choisissez la méthode qui vous convient le mieux. Comme les fichiers binaires peuvent être volumineux, il est souvent nécessaire de fractionner le fichier en plusieurs parties (ou blocs), qui peuvent être envoyées ou reçues dans l’ordre ou en parallèle pour améliorer les performances.

Colonne du nom de fichier

Chaque colonne de fichier a une colonne de chaîne en lecture seule qui contient le nom du fichier. Le nom de schéma pour cette colonne a le même nom que la colonne de fichier, mais _Name lui est ajouté. Donc, si le nom de schéma est sample_FileColumn, la colonne de chaîne complémentaire sera sample_FileColumn_Name. Le nom logique de la colonne complémentaire sera sample_filecolumn_name.

Notes

La colonne du nom de fichier n’apparaît pas dans le concepteur Power Apps.

Relation avec la table FileAttachment

Lorsqu’une colonne de fichier est créée pour une table, une nouvelle relation un-à-plusieurs est créée entre la table et la table FileAttachment. Le nom de la relation est {table logical name}_FileAttachments. Par exemple, si la colonne de fichier fait partie de la table des comptes, le nom de la relation sera account_FileAttachments.

Vous pouvez utiliser cette relation pour renvoyer davantage de données sur la colonne de fichier et toute autre colonne de fichier pour la table. Plus d’informations : Récupérer des informations supplémentaires sur les fichiers pour un enregistrement.

Comportement lors de la récupération

Lorsque vous récupérez un enregistrement et incluez une colonne de fichier, la valeur renvoyée sera un identificateur unique pour le fichier. Vous pouvez utiliser cette valeur pour supprimer le fichier en utilisant le message DeleteFile. Il n’y a pas d’autre utilisation pour cet ID que de vérifier si la colonne a une valeur. Plus d’informations : Utiliser le message DeleteFile.

Les exemples suivants montrent ce à quoi vous pouvez vous attendre lorsque vous récupérez des données de colonnes de fichier comme vous le feriez avec d’autres colonnes.

Ces exemples récupèrent les colonnes name, sample_filecolumn et sample_filecolumn_name pour un enregistrement de compte :

static void RetrieveAccountRecordWithFileColumns(
    IOrganizationService service,
    Guid accountid) 
{

   Entity account = service.Retrieve(
         "account", 
         accountid, 
         new ColumnSet("name", "sample_filecolumn", "sample_filecolumn_name"));

   Console.WriteLine($"name: {account["name"]}");
   Console.WriteLine($"sample_filecolumn: {account["sample_filecolumn"]}");
   Console.WriteLine($"sample_filecolumn_name: {account["sample_filecolumn_name"]}");
}

Sortie :

name: Contoso Ltd.
sample_filecolumn: <file id>
sample_filecolumn_name: 25mb.pdf

Pour plus d’informations :

Récupérer des informations supplémentaires sur les fichiers pour un enregistrement

Vous pouvez utiliser la relation entre la table des colonnes de fichier et la table FileAttachment pour renvoyer des informations sur toutes les colonnes de fichier associées à cette ligne de table.

La méthode statique RetrieveAccountRecordWithFileData montre comment renvoyer des informations sur toutes les colonnes de fichier contenant des données liées à l’enregistrement account avec la valeur accountid correspondante.

static void RetrieveAccountRecordWithFileData(
    IOrganizationService service, 
    Guid accountid)
{
    // Create query for related records
    var relationshipQueryCollection = new RelationshipQueryCollection {
        {
            new Relationship("account_FileAttachments"),
            new QueryExpression("fileattachment"){
                ColumnSet = new ColumnSet(
                                "createdon",
                                "mimetype",
                                "filesizeinbytes",
                                "filename",
                                "regardingfieldname",
                                "fileattachmentid")
            }
        }
    };

    // Include the related query with the Retrieve Request
    RetrieveRequest request = new RetrieveRequest
    {
        ColumnSet = new ColumnSet("accountid"),
        RelatedEntitiesQuery = relationshipQueryCollection,
        Target = new EntityReference("account", accountid)
    };

    // Send the request
    RetrieveResponse response = (RetrieveResponse)service.Execute(request);

    //Display related FileAttachment data for the account record
    response.Entity.RelatedEntities[new Relationship("account_FileAttachments")]
        .Entities.ToList().ForEach(e =>
        {
            Console.WriteLine($"createdon: {e.FormattedValues["createdon"]}");
            Console.WriteLine($"mimetype: {e["mimetype"]}");
            Console.WriteLine($"filesizeinbytes: {e.FormattedValues["filesizeinbytes"]}");
            Console.WriteLine($"filename: {e["filename"]}");
            Console.WriteLine($"regardingfieldname: {e["regardingfieldname"]}");
            Console.WriteLine($"fileattachmentid: {e["fileattachmentid"]}");
        });
}

Sortie :

Dans ce cas, il y a une seule colonne de fichier dans la table des comptes nommée sample_filecolumn, et il s’agit des données sur le fichier stocké dans cette colonne.

createdon: 10/22/2022 2:01 PM
mimetype: application/pdf
filesizeinbytes: 25,870,370
filename: 25mb.pdf
regardingfieldname: sample_filecolumn
fileattachmentid: 63a6afb7-4c52-ed11-bba1-000d3a9933c9

Pour plus d’informations :

Charger des fichiers

Il existe trois manières différentes de charger des fichiers dans une colonne de fichiers :

  • Utiliser les messages Dataverse disponibles à la fois pour le SDK et l’API Web
  • Charger un fichier dans une seule requête en utilisant l’API Web
  • Charger le fichier en blocs en utilisant l’API Web

Notes

Utiliser les messages Dataverse pour charger un fichier

Vous pouvez utiliser les messages Dataverse pour charger un fichier en utilisant le SDK pour .NET ou l’API Web. Charger un fichier de cette manière nécessite d’utiliser un ensemble de trois messages :

Message Description
InitializeFileBlocksUpload Utilisez ce message pour indiquer la colonne dans laquelle vous souhaitez charger un fichier. Il renvoie un jeton de continuation de fichier que vous pouvez utiliser pour charger le fichier en blocs en utilisant le message UploadBlock et avec CommitFileBlocksUpload.
UploadBlock Fractionnez votre fichier en blocs et générez un blockid pour chaque bloc. Ensuite, créez plusieurs requêtes jusqu’à ce que tous les blocs aient été envoyés avec le jeton de continuation de fichier.
CommitFileBlocksUpload Après avoir envoyé des requêtes pour tous les blocs en utilisant UploadBlock, utilisez ce message pour valider l’opération de chargement en envoyant :
- La liste des ID de bloc générés
- Le nom du fichier
- Le type MIME du fichier
- Le jeton de continuation de fichier

Vous pouvez utiliser une fonction comme la suivante pour charger un fichier ou une image en utilisant les classes InitializeFileBlocksUploadRequest, UploadBlockRequest et CommitFileBlocksUploadRequest.

/// <summary>
/// Uploads a file or image column value
/// </summary>
/// <param name="service">The service</param>
/// <param name="entityReference">A reference to the record with the file or image column</param>
/// <param name="fileAttributeName">The name of the file or image column</param>
/// <param name="fileInfo">Information about the file or image to upload.</param>
/// <param name="fileMimeType">The mime type of the file or image, if known.</param>
/// <returns></returns>
static Guid UploadFile(
         IOrganizationService service,
         EntityReference entityReference,
         string fileAttributeName,
         FileInfo fileInfo,
         string fileMimeType = null)
{

   // Initialize the upload
   InitializeFileBlocksUploadRequest initializeFileBlocksUploadRequest = new()
   {
         Target = entityReference,
         FileAttributeName = fileAttributeName,
         FileName = fileInfo.Name
   };

   var initializeFileBlocksUploadResponse =
         (InitializeFileBlocksUploadResponse)service.Execute(initializeFileBlocksUploadRequest);

   string fileContinuationToken = initializeFileBlocksUploadResponse.FileContinuationToken;

   // Capture blockids while uploading
   List<string> blockIds = new();

   using Stream uploadFileStream = fileInfo.OpenRead();

   int blockSize = 4 * 1024 * 1024; // 4 MB

   byte[] buffer = new byte[blockSize];
   int bytesRead = 0;

   long fileSize = fileInfo.Length;
   // The number of iterations that will be required:
   // int blocksCount = (int)Math.Ceiling(fileSize / (float)blockSize);
   int blockNumber = 0;

   // While there is unread data from the file
   while ((bytesRead = uploadFileStream.Read(buffer, 0, buffer.Length)) > 0)
   {
         // The file or final block may be smaller than 4MB
         if (bytesRead < buffer.Length)
         {
            Array.Resize(ref buffer, bytesRead);
         }

         blockNumber++;

         string blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));

         blockIds.Add(blockId);

         // Prepare the request
         UploadBlockRequest uploadBlockRequest = new()
         {
            BlockData = buffer,
            BlockId = blockId,
            FileContinuationToken = fileContinuationToken,
         };

         // Send the request
         service.Execute(uploadBlockRequest);
   }

   // Try to get the mimetype if not provided.
   if (string.IsNullOrEmpty(fileMimeType))
   {
         var provider = new FileExtensionContentTypeProvider();

         if (!provider.TryGetContentType(fileInfo.Name, out fileMimeType))
         {
            fileMimeType = "application/octet-stream";
         }
   }

   // Commit the upload
   CommitFileBlocksUploadRequest commitFileBlocksUploadRequest = new()
   {
         BlockList = blockIds.ToArray(),
         FileContinuationToken = fileContinuationToken,
         FileName = fileInfo.Name,
         MimeType = fileMimeType
   };

   var commitFileBlocksUploadResponse =
         (CommitFileBlocksUploadResponse)service.Execute(commitFileBlocksUploadRequest);

   return commitFileBlocksUploadResponse.FileId;

}

Pour plus d’informations :

Notes

Cet exemple de méthode comprend une certaine logique pour essayer d’obtenir le Type MIME du fichier en utilisant la méthode FileExtensionContentTypeProvider.TryGetContentType(String, String), s’il n’est pas fourni. Si le type est introuvable, il est défini sur application/octet-stream.

Charger un fichier dans une seule requête en utilisant l’API Web

Si la taille du fichier est inférieure à 128 Mo, vous pouvez charger le fichier dans une seule requête en utilisant l’API Web.

L’exemple suivant charge un fichier texte nommé 4094kb.txt dans la colonne de fichier nommée sample_filecolumn de la table account pour un enregistrement avec accountid égal à <accountid>.

Demande :

PATCH [Organization Uri]/api/data/v9.2/accounts(<accountid>)/sample_filecolumn HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: application/octet-stream
x-ms-file-name: 4094kb.txt
Content-Length: 4191273

< binary content removed for brevity>

Réponse :

HTTP/1.1 204 NoContent
OData-Version: 4.0

Exemple PowerShell pour charger un fichier en une seule requête

La fonction PowerShell suivante Set-FileColumn montre comment charger un fichier en une seule requête à l’aide de l’API web.

En savoir plus sur l’utilisation de PowerShell et Visual Studio Code avec l’API web Dataverse :

Cette fonction nécessite une connexion qui définit les paramètres globaux $baseURI et $baseHeaders qui sont configurés à l’aide de la fonction Connect décrite dans Créer une fonction Connect.

<#
.SYNOPSIS
Sets a column value for a file in a specified table.

.DESCRIPTION
The Set-FileColumn function sets a column value for a file in a specified table. 
It uses a single request and can work with files less than 128 MB.

.PARAMETER setName
The entity set name of the table where the file is stored.

.PARAMETER id
The unique identifier of record.

.PARAMETER columnName
The logical name of the file column to set the value for.

.PARAMETER file
The path to the file to upload.

.EXAMPLE
Set-FileColumn `
   -setName 'accounts' `
   -id [System.Guid]::New('12345678-1234-1234-1234-1234567890AB') `
   -columnName 'new_filecolumn' `
   -file 'C:\Path\To\File.txt'
   
Sets the value of the 'new_filecolumn' column for the file with the specified ID 
in the account table to the contents of the File.txt file.

#>
function Set-FileColumn {
   param (
      [Parameter(Mandatory)]
      [string]
      $setName,
      [Parameter(Mandatory)]
      [System.Guid]
      $id,
      [Parameter(Mandatory)]
      [string]
      $columnName,
      [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
      [System.IO.FileInfo]$file
   )

   $uri = '{0}{1}({2})/{3}' -f $baseURI, $setName, $id, $columnName

   $patchHeaders = $baseHeaders.Clone()
   $patchHeaders.Add('Content-Type', 'application/octet-stream')
   $patchHeaders.Add('x-ms-file-name', $file.Name)

   $body = [System.IO.File]::ReadAllBytes($file.FullName)

   $FileUploadRequest = @{
      Uri     = $uri
      Method  = 'Patch'
      Headers = $patchHeaders
      Body    = $body
   }

   Invoke-RestMethod @FileUploadRequest
}

Charger le fichier en blocs en utilisant l’API Web

Pour charger votre fichier en blocs en utilisant l’API Web, utilisez l’ensemble de requêtes suivant.

L’exemple suivant charge un fichier PDF nommé 25mb.pdf dans la colonne de fichier nommée sample_filecolumn de la table account pour un enregistrement avec accountid égal à <accountid>.

Demande :

La première requête doit inclure cet en-tête : x-ms-transfer-mode: chunked

Définissez le nom de fichier en utilisant le paramètre de requête x-ms-file-name.

PATCH [Organization Uri]/api/data/v9.2/accounts(<accountid>)/sample_filecolumn?x-ms-file-name=25mb.pdf HTTP/1.1
x-ms-transfer-mode: chunked
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json

Notes

Le nom de fichier peut également être inclus en tant qu’en-tête de requête x-ms-file-name, mais les noms de fichier en dehors du jeu de caractères ASCII ne seront pas pris en charge. Si l’en-tête est utilisé, il aura la priorité sur le paramètre de requête x-ms-file-name.

Réponse :

HTTP/1.1 200 OK
Accept-Ranges: bytes
Location: [Organization Uri]/api/data/v9.2/accounts(<accountid>)/sample_filecolumn?sessiontoken=<sessiontoken value removed for brevity>
OData-Version: 4.0
x-ms-chunk-size: 4194304
Access-Control-Expose-Headers: x-ms-chunk-size

L’en-tête Location de la réponse comprend une URL à utiliser dans les requêtes ultérieures. Il comprend un paramètre de requête sessiontoken qui indique que toutes les requêtes envoyées via celui-ci font partie de la même opération.

La réponse comprend les en-têtes suivants.

En-tête Description
x-ms-chunk-size Fournit une taille de bloc recommandée en octets.
Accept-Ranges Indique que le serveur prend en charge les requêtes partielles du client pour les téléchargements de fichier. La valeur bytes indique que la valeur de la plage dans les requêtes suivantes doit être en octets.
Access-Control-Expose-Headers Indique que la valeur d’en-tête x-ms-chunk-size doit être mise à la disposition des scripts qui s’exécutent dans le navigateur, en réponse à une requête cross-origin.

Demande :

Les requêtes ultérieures doivent utiliser la valeur de l’en-tête Location renvoyé par la première requête afin que la valeur sessiontoken soit incluse.

Chaque requête doit contenir cette partie du fichier dans le corps et les en-têtes suivants :

En-tête Description
x-ms-file-name Le nom du fichier.
Type de contenu Définir sur application/octet-stream
Content-Range En utilisant ce format :
<unit> <range-start>-<range-end>/<size>
La valeur de la première requête : bytes 0-4194303/25870370 indique que la mesure utilise des octets. Cette requête comprend les 4194303 premiers octets d’un fichier d’une taille de 25870370 octets (presque 25 Mo).
Chaque requête suivante verra cette valeur augmenter jusqu’à ce que tout le fichier ait été envoyé :
bytes 4194304-8388607/25870370
bytes 8388608-12582911/25870370
bytes 12582912-16777215/25870370
bytes 16777216-20971519/25870370
bytes 20971520-25165823/25870370
bytes 25165824-25870369/25870370
Longueur-contenu Indique la taille du message. Dans l’exemple ci-dessus, cette valeur pour la dernière requête sera 704546 au lieu de 4194304.
PATCH [Organization Uri]/api/data/v9.2/accounts(<accountid>)/sample_filecolumn?sessiontoken=<sessiontoken value removed for brevity> HTTP/1.1
x-ms-file-name: 25mb.pdf
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: application/octet-stream
Content-Range: bytes 0-4194303/25870370
Content-Length: 4194304

< byte[] content removed for brevity>

Pour chaque requête contenant un contenu partiel, la réponse sera 206 PartialContent.

Réponse :

HTTP/1.1 206 PartialContent
OData-Version: 4.0

Pour la requête finale qui comprend le dernier bloc du fichier, la réponse sera 204 NoContent.

Réponse :

HTTP/1.1 204 NoContent
OData-Version: 4.0

Exemple PowerShell pour charger un fichier en blocs

La fonction PowerShell suivante Set-FileColumnInChunks montre comment charger un fichier en blocs. Cette fonction nécessite une connexion qui définit les paramètres globaux $baseURI et $baseHeaders qui sont configurés à l’aide de la fonction Connect décrite dans Créer une fonction Connect.

<#
.SYNOPSIS
Sets a column value for a file in a specified table.

.DESCRIPTION
The Set-FileColumnInChunks function sets a column value for a file in a specified table. 
It uses chunked file upload to efficiently upload large files.

.PARAMETER setName
The name of the table where the file is stored.

.PARAMETER id
The unique identifier of record.

.PARAMETER columnName
The logical name of the file column to set the value for.

.PARAMETER file
The path to the file to upload.

.EXAMPLE
Set-FileColumnInChunks `
   -setName 'accounts' `
   -id [System.Guid]::New('12345678-1234-1234-1234-1234567890AB') `
   -columnName 'new_filecolumn' `
   -file 'C:\Path\To\File.txt'
   
Sets the value of the 'new_filecolumn' column for the file with the specified ID in the account table to the contents of the File.txt file.

#>
function Set-FileColumnInChunks {
   param (
      [Parameter(Mandatory)]
      [string]
      $setName,
      [Parameter(Mandatory)]
      [System.Guid]
      $id,
      [Parameter(Mandatory)]
      [string]
      $columnName,
      [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
      [System.IO.FileInfo]$file
   )

   $uri = '{0}{1}({2})' -f $baseURI, $setName, $id
   $uri += '/{0}?x-ms-file-name={1}' -f $columnName, $file.Name

   $chunkHeaders = $baseHeaders.Clone()
   $chunkHeaders.Add('x-ms-transfer-mode', 'chunked')

   $InitializeChunkedFileUploadRequest = @{
      Uri     = $uri
      Method  = 'Patch'
      Headers = $chunkHeaders
   }

   Invoke-RestMethod @InitializeChunkedFileUploadRequest `
      -ResponseHeadersVariable rhv

   $locationUri = $rhv['Location'][0]
   $chunkSize = [int]$rhv['x-ms-chunk-size'][0]

   $bytes = [System.IO.File]::ReadAllBytes($file.FullName)

   for ($offset = 0; $offset -lt $bytes.Length; $offset += $chunkSize) {
         
      $count = if (($offSet + $chunkSize) -gt $bytes.Length) 
                  { $bytes.Length % $chunkSize } 
               else { $chunkSize }
      
      $lastByte = $offset + ($count - 1)

      $range = 'bytes {0}-{1}/{2}' -f $offset, $lastByte, $bytes.Length

      $contentHeaders = $baseHeaders.Clone()
      $contentHeaders.Add('Content-Range', $range)
      $contentHeaders.Add('Content-Type', 'application/octet-stream')
      $contentHeaders.Add('x-ms-file-name', $file.Name)

      $UploadFileChunkRequest = @{
         Uri     = $locationUri
         Method  = 'Patch'
         Headers = $contentHeaders
         Body    = [byte[]]$bytes[$offSet..$lastByte]
      }

      Invoke-RestMethod @UploadFileChunkRequest
   }
}

Vérifier la taille de fichier maximale

Avant de charger un fichier, vous pouvez vérifier si la taille du fichier dépasse la Taille de fichier maximale configurée et stockée dans la propriété MaxSizeInKB.

Si vous essayez de charger un fichier trop volumineux, vous obtiendrez l’erreur suivante :

Nom: unManagedidsattachmentinvalidfilesize
Code : 0x80044a02
Nombre : -2147202558
Message : Attachment file size is too big.

Vous pouvez utiliser les exemples suivants pour vérifier la taille de fichier maximale :

La méthode GetFileColumnMaxSizeInKb statique renvoie la valeur MaxSizeInKB d’une colonne de fichier.

/// <summary>
/// Retrieves the MaxSizeInKb property of a file column.
/// </summary>
/// <param name="service">IOrganizationService</param>
/// <param name="entityLogicalName">The logical name of the table that has the column</param>
/// <param name="fileColumnLogicalName">The logical name of the file column.</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static int GetFileColumnMaxSizeInKb(
    IOrganizationService service, 
    string entityLogicalName, 
    string fileColumnLogicalName) 
{

   RetrieveAttributeRequest retrieveAttributeRequest = new() { 
         EntityLogicalName = entityLogicalName,
         LogicalName = fileColumnLogicalName
   };

   RetrieveAttributeResponse retrieveAttributeResponse;
   try
   {
         retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);
   }
   catch (Exception)
   {
         throw;
   }

   if (retrieveAttributeResponse.AttributeMetadata is FileAttributeMetadata fileColumn)
   {
         return fileColumn.MaxSizeInKB.Value;
   }
   else
   {
         throw new Exception($"{entityLogicalName}.{fileColumnLogicalName} is not a file column.");
   }
}

Pour plus d’informations :

Télécharger des fichiers

Il existe trois méthodes différentes pour télécharger des fichiers à partir d’une colonne de fichiers :

  • Utiliser les messages Dataverse disponibles à la fois pour le SDK et l’API Web
  • Télécharger un fichier dans une seule requête en utilisant l’API Web
  • Télécharger le fichier en blocs en utilisant l’API Web

Notes

Ces méthodes peuvent également servir à télécharger des colonnes d’images, mais il existe quelques différences. Plus d’informations : Télécharger des images

Pour les environnements locaux ou lorsqu’un environnement utilise la Clé gérée automatiquement (BYOK), le fichier n’est pas dans le stockage de fichiers. Lorsqu’un fichier n’est pas dans le stockage de fichiers, le téléchargement segmenté n’est pas pris en charge. Le ComplexType InitializeFileBlocksDownloadResponse et la Classe InitializeFileBlocksDownloadResponse ont une propriété IsChunkingSupported qui indique si le fichier peut être téléchargé de façon segmentée ou non. Si la segmentation n’est pas prise en charge, définissez BlockLength à la taille du fichier.

Essayer de télécharger un morceau partiel alors que IsChunkingSupported est défini sur false entraîne cette erreur :

Nom: UploadingAndDownloadingInMultipleChunksNotSupported
Code : 0x80090017
Message : Downloading in multiple chunks is not supported for the files stored in the database.

Utilisez les messages Dataverse pour télécharger un fichier

Vous pouvez utiliser les messages Dataverse pour charger un fichier en utilisant le SDK pour .NET ou l’API Web. Télécharger un fichier de cette manière nécessite d’utiliser une paire de messages :

Message Description
InitializeFileBlocksDownload Utilisez ce message pour indiquer la colonne à partir de laquelle vous souhaitez télécharger un fichier. Il renvoie le taille de fichier en octets et un jeton de continuation de fichier que vous pouvez utiliser pour télécharger le fichier en blocs en utilisant le message DownloadBlock.
DownloadBlock Demandez la taille du bloc, la valeur de décalage et le jeton de continuation de fichier.

Une fois que vous avez téléchargé tous les blocs, vous devez les joindre pour créer le fichier téléchargé complet.

Vous pouvez utiliser une fonction comme la suivante pour télécharger un fichier ou une image avec le kit SDK en utilisant les classes InitializeFileBlocksDownloadRequest et DownloadBlockRequest.

/// <summary>
/// Downloads a file or image
/// </summary>
/// <param name="service">The service</param>
/// <param name="entityReference">A reference to the record with the file or image column</param>
/// <param name="attributeName">The name of the file or image column</param>
/// <returns></returns>
private static byte[] DownloadFile(
            IOrganizationService service,
            EntityReference entityReference,
            string attributeName)
{
   InitializeFileBlocksDownloadRequest initializeFileBlocksDownloadRequest = new()
   {
         Target = entityReference,
         FileAttributeName = attributeName
   };

   var initializeFileBlocksDownloadResponse =
         (InitializeFileBlocksDownloadResponse)service.Execute(initializeFileBlocksDownloadRequest);

   string fileContinuationToken = initializeFileBlocksDownloadResponse.FileContinuationToken;
   long fileSizeInBytes = initializeFileBlocksDownloadResponse.FileSizeInBytes;

   List<byte> fileBytes = new((int)fileSizeInBytes);

   long offset = 0;
   // If chunking is not supported, chunk size will be full size of the file.
   long blockSizeDownload = !initializeFileBlocksDownloadResponse.IsChunkingSupported ? fileSizeInBytes :  4 * 1024 * 1024;

   // File size may be smaller than defined block size
   if (fileSizeInBytes < blockSizeDownload)
   {
         blockSizeDownload = fileSizeInBytes;
   }

   while (fileSizeInBytes > 0)
   {
         // Prepare the request
         DownloadBlockRequest downLoadBlockRequest = new()
         {
            BlockLength = blockSizeDownload,
            FileContinuationToken = fileContinuationToken,
            Offset = offset
         };

         // Send the request
         var downloadBlockResponse =
                  (DownloadBlockResponse)service.Execute(downLoadBlockRequest);

         // Add the block returned to the list
         fileBytes.AddRange(downloadBlockResponse.Data);

         // Subtract the amount downloaded,
         // which may make fileSizeInBytes < 0 and indicate
         // no further blocks to download
         fileSizeInBytes -= (int)blockSizeDownload;
         // Increment the offset to start at the beginning of the next block.
         offset += blockSizeDownload;
   }

   return fileBytes.ToArray();
}

Pour plus d’informations :

Télécharger un fichier dans une seule requête en utilisant l’API Web

L’exemple suivant télécharge un fichier texte nommé 4094kb.txt à partir de la colonne de fichier nommée sample_filecolumn de la table account pour un enregistrement avec accountid égal à <accountid>.

Demande :

GET [Organization Uri]/api/data/v9.2/accounts(<accountid>)/sample_filecolumn/$value HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json

Réponse :

La réponse comprend les en-têtes suivants.

En-tête Description
x-ms-file-size Taille du fichier en octets.
x-ms-file-name Le nom du fichier.
mimetype Le type MIME du fichier.
Access-Control-Expose-Headers Indique que les valeurs d’en-tête x-ms-file-size, x-ms-file-name et mimetype doivent être mises à la disposition des scripts qui s’exécutent dans le navigateur, en réponse à une requête cross-origin.
HTTP/1.1 200 OK
x-ms-file-size: 4191273
x-ms-file-name: 4094kb.txt
mimetype: text/plain
Access-Control-Expose-Headers: x-ms-file-size; x-ms-file-name; mimetype

< byte[] content removed for brevity. >

Télécharger le fichier en blocs en utilisant l’API Web

Notes

L’exemple ci-dessous concerne les cas où IsChunkingSupported est défini sur True. Si défini sur False, utilisez Télécharger un fichier en une seule requête à l’aide de l’API web.

Pour télécharger votre fichier en blocs en utilisant l’API Web, utilisez l’ensemble de requêtes suivant.

L’exemple suivant télécharge un fichier PDF nommé 25mb.pdf dans la colonne de fichier nommée sample_filecolumn de la table account pour un enregistrement avec accountid égal à <accountid>.

Demande :

Utilisez l’en-tête Range pour spécifier le nombre d’octets à renvoyer en utilisant ce format :
<unit>=<range-start>-<range-end>
Où la valeur unit est Octets et la valeur range-start pour la première requête est 0.

Vous ne saurez pas combien d’itérations sont nécessaires pour télécharger tout le fichier jusqu’à ce que vous obteniez la première réponse où l’en-tête de réponse x-ms-file-size vous indique la taille du fichier.

Lorsque la valeur <range-start> est inférieure à la taille totale du fichier, pour chaque requête ultérieure, incrémentez les valeurs <range-start> et <range-end> pour demander le bloc suivant du fichier.

GET [Organization Uri]/api/data/v9.2/accounts(<accountid>)/sample_filecolumn/$value HTTP/1.1
Range: bytes=0-4194303
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json

Réponse :

La réponse comprend les en-têtes suivants :

En-tête Description
x-ms-file-size Taille du fichier en octets.
x-ms-file-name Le nom du fichier.
x-ms-chunk-size Fournit une taille de bloc recommandée en octets.
mimetype Le type MIME du fichier.
Access-Control-Expose-Headers Indique que les valeurs d’en-tête x-ms-file-size, x-ms-file-name, x-ms-chunk-size et mimetype doivent être mises à la disposition des scripts qui s’exécutent dans le navigateur, en réponse à une requête cross-origin.
HTTP/1.1 206 PartialContent
x-ms-file-size: 25870370
x-ms-file-name: 25mb.pdf
x-ms-chunk-size: 4194304
mimetype: application/pdf
Access-Control-Expose-Headers: x-ms-file-size; x-ms-file-name; x-ms-chunk-size; mimetype
OData-Version: 4.0

< byte[] content removed for brevity. >

Supprimer des fichiers

Il existe deux manières différentes de supprimer des fichiers dans une colonne de fichiers :

  • Utiliser le message DeleteFile de Dataverse disponible à la fois pour le SDK et l’API Web
  • Envoyer une requête DELETE en utilisant l’API Web à la colonne de fichier de l’enregistrement.

Utiliser le message DeleteFile

En utilisant l’identificateur unique renvoyé par CommitFileBlocksUploadResponse.FileId ou récupéré de la colonne comme décrit dans Comportement lors de la récupération, vous pouvez supprimer le fichier en utilisant le message DeleteFile.

Vous pouvez utiliser une fonction comme la suivante pour supprimer un fichier avec l’identificateur unique en utilisant la Classe DeleteFileRequest.

static Guid DeleteFile(IOrganizationService service, Guid fileId)
{
   DeleteFileRequest deleteFileRequest = new()
   {
      FileId = fileId
   };
   service.Execute(deleteFileRequest);
}

Envoyer la requête DELETE à la colonne de fichier

Avec l’API Web, vous pouvez supprimer un fichier en envoyant une requête DELETE à l’emplacement de la ressource du fichier.

L’exemple suivant supprime des données de fichier d’une colonne nommée sample_filecolumn de la table account pour un enregistrement avec accountid égal à <accountid>.

Demande :

DELETE [Organization Uri]/api/data/v9.2/accounts(<accountid>)/sample_filecolumn HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json

Réponse :

HTTP/1.1 204 NoContent
OData-Version: 4.0

Plus d’informations : Supprimer une valeur de propriété unique

Voir aussi

Vue d’ensemble des fichiers et des images
Types de données de colonne > Colonnes de fichier
Utiliser des définitions de colonne de fichier avec du code
Exemple : opérations de fichier en utilisant le SDK Dataverse pour .NET
Exemple : opérations de fichier en utilisant l’API Web de Dataverse

Notes

Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)

Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).