Compartilhar via


Utilizar os dados da coluna de arquivo no Microsoft Dataverse

As colunas de arquivo no Microsoft Dataverse diferem de outras colunas do sistema que armazenam dados binários porque você não pode definir diretamente os valores em uma operação de criação ou atualização ou recuperar os dados do arquivo com o registro. Para criar, recuperar, atualizar ou excluir dados binários para colunas de arquivo, use os métodos descritos neste artigo. Saiba como carregar, baixar e excluir arquivos usando o SDK para .NET e a API Web, incluindo suporte para transferências em partes de arquivos grandes.

Você pode trabalhar com dados de coluna de arquivo usando vários métodos diferentes por meio da API Web. Todos os métodos têm suporte igual, portanto, escolha o método que funciona melhor para você. Como os arquivos binários podem ser grandes, você geralmente precisa dividir o arquivo em várias partes (ou blocos) que você pode enviar ou receber sequencialmente ou em paralelo para melhorar o desempenho.

Coluna nome do arquivo

Cada coluna de arquivo tem uma coluna de string de suporte somente leitura que contém o nome do arquivo. O nome do esquema dessa coluna tem o mesmo nome da coluna de arquivo, mas com _Name acrescentado a ela. Portanto, se o nome do esquema for sample_FileColumn, a coluna de cadeia de caracteres de suporte será sample_FileColumn_Name. O nome lógico da coluna de suporte é sample_filecolumn_name.

Observação

A coluna nome do arquivo não aparece no designer do Power Apps .

Relacionamento com a tabela FileAttachment

Ao criar uma coluna de arquivo para uma tabela, você também cria uma nova relação um-para-muitos entre essa tabela e a tabela FileAttachment. O nome da relação é {table logical name}_FileAttachments. Por exemplo, se a coluna de arquivo fizer parte da tabela de conta, o nome da relação será account_FileAttachments.

Você pode usar essa relação para retornar mais dados sobre a coluna de arquivo e quaisquer outras colunas de arquivo para a tabela. Para obter mais informações, consulte Recuperar informações adicionais sobre arquivos para um registro

Comportamento ao recuperar dados

Quando você recupera um registro e inclui uma coluna de arquivo, o valor retornado é um identificador exclusivo para o arquivo. Você pode usar esse valor para excluir o arquivo usando a DeleteFile mensagem. Não há outro uso para essa ID além de verificar se a coluna tem um valor. Para obter mais informações, consulte Usar a mensagem DeleteFile.

Os exemplos a seguir mostram o que você pode esperar ao recuperar dados de colunas de arquivo, como faria com outras colunas.

Estes exemplos recuperam as colunas name, sample_filecolumn e sample_filecolumn_name de um registro de conta.

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"]}");
}

Saída:

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

Mais informações:

Recuperar informações extras sobre arquivos para um registro

Você pode usar a relação entre a tabela de colunas de arquivo e a FileAttachment tabela para retornar informações sobre todas as colunas de arquivo associadas a essa linha de tabela.

O RetrieveAccountRecordWithFileData método estático mostra como retornar informações sobre todas as colunas de arquivo que contêm dados relacionados ao account registro com o valor correspondente accountid .

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"]}");
        });
}

Saída:

Nesse caso, há uma única coluna de arquivo na tabela de contas chamada sample_filecolumn, e esses são os dados sobre o arquivo armazenado nessa coluna.

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

Mais informações:

Carregar arquivos

Você pode carregar arquivos em uma coluna de arquivo de três maneiras diferentes:

  • Usar mensagens do Dataverse disponíveis para o SDK e a API Web
  • Carregar um arquivo em uma única solicitação usando a API Web
  • Carregar o arquivo em partes usando a API Web

Observação

  • Verifique se o tamanho máximo do arquivo da coluna é grande o suficiente para aceitar o arquivo que você está carregando. Para obter mais informações, consulte Verificar o tamanho máximo do arquivo.
  • Você também pode usar essas APIs para carregar dados de coluna de imagem. Para obter mais informações, consulte Usar dados de coluna de imagem.

Usar mensagens do Dataverse para carregar um arquivo

Você pode usar mensagens do Dataverse usando o SDK para .NET ou API Web. Carregar um arquivo dessa forma requer o uso de um conjunto de três mensagens:

Mensagem Descrição
InitializeFileBlocksUpload Use esta mensagem para indicar a coluna para a qual você deseja carregar um arquivo. Ele retorna um token de continuação de arquivo que você pode usar para carregar o arquivo em blocos usando a UploadBlock mensagem e com CommitFileBlocksUpload.
UploadBlock Divida o arquivo em blocos e gere um blockid para cada bloco. Em seguida, faça várias solicitações até que todos os blocos sejam enviados junto com o token de continuação de arquivo.
CommitFileBlocksUpload Depois de enviar solicitações para todos os blocos usando UploadBlock, use esta mensagem para confirmar a operação de upload enviando:
- A lista de blockids gerados
- O nome do arquivo
- O tipo MIME do arquivo
- O token de continuação de arquivo

Para carregar um arquivo ou imagem, use uma função como a seguinte que usa as classes InitializeFileBlocksUploadRequest, UploadBlockRequest e 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;

}

Mais informações:

Observação

Este método de exemplo inclui alguma lógica para tentar obter o tipo MIME do arquivo usando o método FileExtensionContentTypeProvider.TryGetContentType(String, String) se ele não for fornecido. Se o tipo não for encontrado, ele será definido como application/octet-stream.

Carregar um arquivo em uma única solicitação usando a API Web

Se o tamanho do arquivo for menor que 128 MB, você poderá carregar o arquivo em uma única solicitação usando a API Web.

O exemplo a seguir carrega um arquivo de texto nomeado 4094kb.txt para a coluna de arquivo nomeada sample_filecolumn na account tabela para um registro com accountid igual a <accountid>.

Solicitação:

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>

Resposta:

HTTP/1.1 204 NoContent
OData-Version: 4.0

Exemplo do PowerShell para carregar o arquivo em uma única solicitação

A função do PowerShell Set-FileColumn a seguir demonstra como carregar um arquivo em uma única solicitação usando a API Web.

Para saber mais sobre como usar o PowerShell e o Visual Studio Code com a API Web do Dataverse, consulte:

Essa função requer uma conexão que define o global $baseURI e $baseHeaders. Defina esses valores usando a Connect função descrita em Criar uma função 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
}

Carregar o arquivo em partes usando a API Web

Para carregar seu arquivo em partes usando a API Web, use o seguinte conjunto de solicitações.

O exemplo a seguir carrega um arquivo PDF nomeado 25mb.pdf para a coluna de arquivo nomeada sample_filecolumn na account tabela para um registro com accountid igual a <accountid>.

Solicitação:

A primeira solicitação deve incluir este cabeçalho: x-ms-transfer-mode: chunked.

Defina o nome do arquivo usando o x-ms-file-name parâmetro de consulta.

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

Observação

Você também pode incluir o nome do arquivo como um x-ms-file-name cabeçalho de solicitação, mas essa abordagem não dá suporte a nomes de arquivo fora do conjunto de caracteres ASCII. Se você usar o cabeçalho, ele terá precedência sobre o x-ms-file-name parâmetro de consulta.

Resposta:

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

O cabeçalho local da resposta inclui uma URL a ser usada nas solicitações subsequentes. Ele inclui um sessiontoken parâmetro de consulta que indica que todas as solicitações enviadas usando-o fazem parte da mesma operação.

A resposta inclui os cabeçalhos a seguir.

Cabeçalho Descrição
x-ms-chunk-size Fornece um tamanho de bloco recomendado em bytes.
Intervalos de aceitação Indica que o servidor dá suporte a solicitações parciais do cliente para downloads de arquivo. O valor bytes indica que o valor do intervalo nas solicitações subsequentes deve estar em bytes.
Access-Control-Expose-Headers Indica que o valor do x-ms-chunk-size cabeçalho deve ser disponibilizado para scripts em execução no navegador, em resposta a uma solicitação entre diferentes origens.

Solicitação:

As solicitações subsequentes devem usar o valor do Location cabeçalho retornado pela primeira solicitação para que o sessiontoken valor seja incluído.

Cada solicitação deve conter essa parte do arquivo no corpo e os seguintes cabeçalhos:

Cabeçalho Descrição
x-ms-file-name O nome do arquivo.
Tipo de conteúdo Definida como application/octet-stream
Intervalo de conteúdo Usando este formato:
<unit> <range-start>-<range-end>/<size>
O valor da primeira solicitação: bytes 0-4194303/25870370 indica que a medida está usando bytes. A solicitação inclui os primeiros 4194303 bytes de um arquivo que tem 25870370 bytes de tamanho, aproximadamente 25 MB.
Cada solicitação subsequente aumenta esse valor até que todo o arquivo seja enviado:
bytes 4194304-8388607/25870370
bytes 8388608-12582911/25870370
bytes 12582912-16777215/25870370
bytes 16777216-20971519/25870370
bytes 20971520-25165823/25870370
bytes 25165824-25870369/25870370
Content-Length Indica o tamanho da mensagem. No exemplo anterior, esse valor para a última solicitação é 704546 em vez 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>

Para cada solicitação que contém conteúdo parcial, a resposta é 206 PartialContent.

Resposta:

HTTP/1.1 206 PartialContent
OData-Version: 4.0

Para a solicitação final que inclui a última parte do arquivo, a resposta é 204 NoContent.

Resposta:

HTTP/1.1 204 NoContent
OData-Version: 4.0

Exemplo do PowerShell para carregar o arquivo em partes

A função do PowerShell Set-FileColumnInChunks a seguir demonstra como carregar um arquivo em partes. Essa função requer uma conexão que defina os globais $baseURI e $baseHeaders usando a função Connect descrita em Criar uma função 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
   }
}

Verificar o tamanho máximo do arquivo

Antes de carregar um arquivo, verifique se o tamanho do arquivo excede o tamanho máximo do arquivo configurado armazenado na MaxSizeInKB propriedade.

Se você tentar carregar um arquivo muito grande, receberá a seguinte mensagem de erro:

Nome: unManagedidsattachmentinvalidfilesize
Código: 0x80044a02
Número: -2147202558
Mensagem: Attachment file size is too big.

Use os seguintes exemplos para verificar o tamanho máximo do arquivo:

O método estático GetFileColumnMaxSizeInKb retorna o MaxSizeInKB valor de uma coluna de arquivo.

/// <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.");
   }
}

Mais informações:

Baixar arquivos

Você pode usar três métodos diferentes para baixar arquivos de uma coluna de arquivo:

  • Usar mensagens do Dataverse disponíveis para o SDK e a API Web
  • Baixar um arquivo em uma única solicitação usando a API Web
  • Baixar o arquivo em partes usando a API Web

Observação

Você também pode usar esses métodos para baixar colunas de imagem, mas há algumas diferenças. Para obter mais informações, consulte Baixar imagens.

Para ambientes locais ou quando um ambiente usa uma BYOK (chave autogerenciada), o arquivo não está no armazenamento de arquivos. Quando um arquivo não está no armazenamento de arquivos, não há suporte para o download em várias partes. A classe InitializeFileBlocksDownloadResponse ComplexType e InitializeFileBlocksDownloadResponse tem uma IsChunkingSupported propriedade que indica se o arquivo pode ser baixado em várias partes ou não. Se não houver suporte para agrupamento, o BlockLength valor será definido como o tamanho do arquivo.

Tentar baixar um bloco parcial quando IsChunkingSupported está definido como falso resulta neste erro:

Nome: UploadingAndDownloadingInMultipleChunksNotSupported
Código: 0x80090017
Mensagem: Downloading in multiple chunks isn't supported for the files stored in the database.

Usar mensagens do Dataverse para baixar um arquivo

Você pode usar mensagens do Dataverse usando o SDK para .NET ou API Web. Baixar um arquivo dessa forma requer o uso de um par de mensagens:

Mensagem Descrição
InitializeFileBlocksDownload Use esta mensagem para indicar a coluna da qual você deseja baixar um arquivo. Ele retorna o tamanho do arquivo em bytes e um token de continuação de arquivo que você pode usar para baixar o arquivo em blocos usando a DownloadBlock mensagem.
DownloadBlock Solicite o tamanho do bloco, o valor de offset e o token de continuação do arquivo.

Depois de baixar todos os blocos, você deve juntá-los para criar todo o arquivo baixado.

Você pode usar uma função como a seguinte para baixar um arquivo ou imagem usando as classes SDK e InitializeFileBlocksDownloadRequest e 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();
}

Mais informações:

Baixar um arquivo em uma única solicitação usando a API Web

O exemplo a seguir baixa um arquivo de texto nomeado 4094kb.txt da coluna de arquivo nomeada sample_filecolumn na account tabela para um registro com accountid igual a <accountid>.

Solicitação:

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

Resposta:

A resposta inclui os cabeçalhos a seguir.

Cabeçalho Descrição
x-ms-file-size O tamanho do arquivo em bytes.
x-ms-file-name O nome do arquivo.
mimetype O tipo MIME do arquivo.
Access-Control-Expose-Headers Indica que os valores de cabeçalho x-ms-file-size, x-ms-file-name e mimetype estão disponíveis para scripts em execução no navegador, em resposta a uma solicitação entre origens.
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. >

Baixar o arquivo em partes usando a API Web

Observação

O exemplo a seguir funciona quando IsChunkingSupported é definido como true. Se for falso, use Baixar um arquivo em uma única solicitação usando a API Web.

Para baixar o arquivo em partes usando a API Web, use o seguinte conjunto de solicitações.

O exemplo a seguir baixa um arquivo PDF nomeado 25mb.pdf para a coluna de arquivo nomeada sample_filecolumn na account tabela para um registro com accountid igual a <accountid>.

Solicitação:

Use o cabeçalho Range para especificar o número de bytes a serem retornados usando este formato:
<unit>=<range-start>-<range-end>
Onde unit são bytes e range-start para a primeira solicitação é 0.

Você não sabe quantas iterações são necessárias para baixar o arquivo inteiro até obter a primeira resposta em que o x-ms-file-size cabeçalho de resposta informa o tamanho do arquivo.

Embora o <range-start> seja menor que o tamanho total do arquivo, para cada solicitação subsequente, incremente os valores de <range-start> e <range-end> para solicitar a próxima parte do arquivo.

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

Resposta:

A resposta inclui os seguintes cabeçalhos:

Cabeçalho Descrição
x-ms-file-size O tamanho do arquivo em bytes.
x-ms-file-name O nome do arquivo.
x-ms-chunk-size Fornece um tamanho de bloco recomendado em bytes.
mimetype O tipo MIME do arquivo.
Access-Control-Expose-Headers Indica que os valores de cabeçalho x-ms-file-size, x-ms-file-name, x-ms-chunk-size e mimetype devem estar disponíveis para scripts em execução no navegador, em resposta a uma solicitação de origem cruzada.
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. >

Eliminar ficheiros

Você pode excluir arquivos em uma coluna de arquivo usando um dos seguintes métodos:

  • Use a mensagem do Dataverse DeleteFile , que está disponível para o SDK e a API Web.
  • Envie uma solicitação DELETE usando a API Web para a coluna de arquivo do registro.

Use a mensagem DeleteFile

Usando o identificador exclusivo retornado de CommitFileBlocksUploadResponse.FileId ou recuperado da coluna, conforme descrito em Comportamento ao recuperar, é possível excluir o arquivo usando a mensagem de DeleteFile.

Use uma função como o exemplo a seguir para excluir um arquivo usando o identificador exclusivo e a Classe DeleteFileRequest.

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

Enviar solicitação DELETE para a coluna de arquivo

Usando a API Web, você pode excluir um arquivo enviando uma DELETE solicitação para o local do recurso de arquivo.

O exemplo a seguir exclui dados de arquivo de uma coluna nomeada sample_filecolumn na account tabela para um registro com accountid igual a <accountid>.

Solicitação:

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

Resposta:

HTTP/1.1 204 NoContent
OData-Version: 4.0

Mais informações: Excluir um único valor de propriedade

Consulte também

Visão geral de arquivos e imagens
Tipos de dados de coluna > Colunas de arquivo
Trabalhar com definições de coluna de arquivo usando código
Exemplo: Operações de arquivo usando o SDK do Dataverse para .NET
Exemplo: Operações de arquivo usando a API Web do Dataverse.