Usar datos de columna de archivo
Las columnas de archivo son diferentes de las otras columnas del sistema que pueden almacenar datos binarios porque no puede establecer los valores directamente en una operación de creación o actualización ni recuperar los datos del archivo con el registro. Debe usar los métodos descritos en este artículo para crear, recuperar, actualizar o eliminar datos binarios para columnas de archivos.
Hay varias formas diferentes de trabajar con datos de columnas de archivos mediante la API web. Todos los métodos son compatibles por igual. Elija el método que funcione mejor para usted. Debido a que los archivos binarios pueden ser grandes, con frecuencia es necesario dividir el archivo en varios fragmentos (o bloques) que se pueden enviar o recibir secuencialmente o en paralelo para mejorar el rendimiento.
Columna de nombre de archivo
Cada columna de archivo tiene una columna de cadena de solo lectura que contiene el nombre del archivo. El nombre de esquema para esta columna tiene el mismo nombre que la columna del archivo, pero tiene _Name
anexado a ella. Entonces, si el nombre del esquema es sample_FileColumn
, la columna de cadena de apoyo será sample_FileColumn_Name
. El nombre lógico de la columna de apoyo será sample_filecolumn_name
.
Nota
La columna de nombre de archivo no aparece en el diseñador de Power Apps.
Relación con la tabla FileAttachment
Cuando se crea una columna de archivo para una tabla, se crea una nueva relación de uno a varios entre la tabla y la tabla FileAttachment
. El nombre de la relación es {table logical name}_FileAttachments
. Por ejemplo, si la columna del archivo es parte de la tabla de cuentas, el nombre de la relación será account_FileAttachments
.
Puede usar esta relación para devolver más datos sobre la columna de archivo y cualquier otra columna de archivo para la tabla. Más información: Recuperar información adicional sobre archivos para un registro.
Comportamiento al recuperar
Cuando recupera un registro e incluye una columna de archivo, el valor devuelto será un identificador único para el archivo. Puede usar este valor para eliminar el archivo usando el mensaje DeleteFile
. No hay otro uso para esta ID que no sea verificar si la columna tiene un valor. Más información: Usar el mensaje DeleteFile.
Los siguientes ejemplos muestran lo que puede esperar al recuperar datos de columnas de archivos como lo haría con otras columnas.
Estos ejemplos recuperan las columnas name
, sample_filecolumn
y sample_filecolumn_name
para un registro de cuenta:
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"]}");
}
Salida:
name: Contoso Ltd.
sample_filecolumn: <file id>
sample_filecolumn_name: 25mb.pdf
Más información:
Recuperar información adicional sobre archivos para un registro
Puede utilizar la relación entre la tabla de columnas del archivo y la tabla FileAttachment
para devolver información sobre todas las columnas del archivo asociadas a esa fila de la tabla.
El método estático RetrieveAccountRecordWithFileData
musetra cómo devolver información sobre todas las columnas del archivo que contienen datos relacionados con el registro account
con el valor coincidente 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"]}");
});
}
Salida:
En este caso, hay una sola columna de archivo en la tabla de cuentas denominada sample_filecolumn
, y estos son los datos sobre el archivo almacenado en esa columna.
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
Más información:
Cargar archivos
Hay tres formas diferentes de cargar archivos en una columna de archivos:
- Usar mensajes de Dataverse disponibles tanto para el SDK Webcomo para la API web
- Cargar un archivo en una sola solicitud usando la API web
- Cargar el archivo en fragmentos utilizando la API web
Nota
- Debe verificar si el tamaño máximo de archivo de la columna es lo suficientemente grande para aceptar el archivo que está cargando. Más información: Comprobar el tamaño máximo del archivo.
- También puede usar estas API para cargar datos de columnas de imágenes. Más información: Usar datos de columna de imagen
Usar mensajes de Dataverse para subir un archivo
Puedes usar mensajes de Dataverse usando el SDK para .NET o API web. Cargar un archivo de esta manera requiere el uso de un conjunto de tres mensajes:
Publicación | Descripción |
---|---|
InitializeFileBlocksUpload |
Utilice este mensaje para indicar la columna en la que desea cargar un archivo. Devuelve un token de continuación de archivo que puede usar para cargar el archivo en bloques usando el mensaje UploadBlock y con CommitFileBlocksUpload . |
UploadBlock |
Divida su archivo en bloques y genere un blockid para cada bloque. Luego haga varias solicitudes hasta que todos los bloques se hayan enviado junto con el token de continuación del archivo. |
CommitFileBlocksUpload |
Después de haber enviado solicitudes para todos los bloques usando UploadBlock , use este mensaje para confirmar la operación de carga enviando:- La lista de id. de bloques generados - El nombre del archivo - El tipo MIME del archivo - El token de continuación del archivo |
Puede usar una función como la siguiente para cargar un archivo o imagen usando las clases InitializeFileBlocksUploadRequest, UploadBlockRequest y 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;
}
Más información:
Nota
Este método de ejemplo incluye algo de lógica para tratar de obtener el Tipo de MIME del archivo usando el Método FileExtensionContentTypeProvider.TryGetContentType(String, String) si no se proporciona. Si el tipo de datos no se encuentra, se establece en application/octet-stream
.
Cargar un archivo en una sola solicitud usando la API web
Si el tamaño del archivo es inferior a 128 MB, puede cargar el archivo en una sola solicitud mediante la API web.
El siguiente ejemplo carga un archivo de texto llamado 4094kb.txt
a la columna del archivo denominada sample_filecolumn
en la tabla account
para un registro con accountid
igual a <accountid>
.
Solicitud:
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>
Respuesta:
HTTP/1.1 204 NoContent
OData-Version: 4.0
Ejemplo de PowerShell para cargar archivos en una sola solicitud
La siguiente función de PowerShell Set-FileColumn
demuestra cómo cargar un archivo en una sola solicitud utilizando Web API.
Obtenga más información sobre el uso de PowerShell y Visual Studio Code con la API web Dataverse:
- Inicio rápido de la API web con PowerShell y Visual Studio Code
- Use PowerShell y Visual Studio Code con la API web de Dataverse
Esta función requiere una conexión que establezca el valor global $baseURI
y $baseHeaders
que se configuran usando la función Connect
descrita en Crear una función 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
}
Cargar el archivo en fragmentos utilizando la API web
Para cargar su archivo en fragmentos usando la API web, use el siguiente conjunto de solicitudes.
El siguiente ejemplo carga un archivo PDF llamado 25mb.pdf
a la columna del archivo denominada sample_filecolumn
en la tabla account
para un registro con accountid
igual a <accountid>
.
Solicitud:
La primera solicitud debe incluir este encabezado:x-ms-transfer-mode: chunked
Establezca el nombre del archivo con el parámetro de consulta 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
Nota
El nombre del archivo también se puede incluir como encabezado de solicitud x-ms-file-name
, pero esto no admitirá nombres de archivo fuera del conjunto de caracteres ASCII. Si se utiliza el encabezado, tendrá prioridad sobre el parámetro de consulta x-ms-file-name
.
Respuesta:
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
La respuesta de encabezado Ubicación incluye una URL para usar en solicitudes posteriores. Incluye un parámetro de consulta sessiontoken
que indica que todas las solicitudes enviadas a través de él forman parte de la misma operación.
La respuesta incluye los siguientes encabezados.
Encabezado | Descripción |
---|---|
x-ms-chunk-size |
Proporciona un tamaño de fragmento recomendado en bytes. |
Accept-Ranges | Indica que el servidor admite solicitudes parciales del cliente para descargas de archivos. El valor bytes indica que el valor del rango en las solicitudes posteriores debe estar en bytes. |
Access-Control-Expose-Headers | Indica que el valor de encabezado x-ms-chunk-size debe estar disponible para los scripts que se ejecutan en el navegador, en respuesta a una solicitud de origen cruzado. |
Solicitud:
Las solicitudes subsiguientes deben utilizar el valor del encabezado Location
devuelto por la primera solicitud para que el valor sessiontoken
se incluya.
Cada solicitud debe contener esa parte del archivo en el cuerpo y los siguientes encabezados:
Encabezado | Descripción |
---|---|
x-ms-file-name |
El nombre del archivo. |
Tipo de contenido | Configurar application/octet-stream |
Content-Range | Con este formato: <unit> <range-start>-<range-end>/<size> El valor de la primera solicitud: bytes 0-4194303/25870370 indica que la medida está utilizando bytes. Esta solicitud incluye los primeros 4194303 bytes de un archivo que de 25870370 bytes (casi 25 MB) de tamaño.Cada solicitud posterior verá aumentar este valor hasta que se haya enviado el archivo completo: 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 el tamaño del mensaje. En el ejemplo anterior, este valor para la última solicitud será 704546 en 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 solicitud que contenga contenido parcial, la respuesta será 206 PartialContent.
Respuesta:
HTTP/1.1 206 PartialContent
OData-Version: 4.0
Para la solicitud final que incluye el último fragmento del archivo, la respuesta será 204 NoContent.
Respuesta:
HTTP/1.1 204 NoContent
OData-Version: 4.0
Ejemplo de PowerShell para cargar archivos en trozos
La siguiente función de PowerShell Set-FileColumnInChunks
demuestra cómo cargar un archivo en trozos. Esta función requiere una conexión que establezca el valor global $baseURI
y $baseHeaders
que se configuran usando la función Connect
descrita en Crear una función 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
}
}
Comprobar el tamaño de archivo máximo
Antes de cargar un archivo, puede verificar si el tamaño del archivo excede el Tamaño máximo de archivo configurado y almacenado en la propiedad MaxSizeInKB
.
Si intenta cargar un archivo que es demasiado grande, obtendrá el siguiente error:
Nombre:
unManagedidsattachmentinvalidfilesize
Código:0x80044a02
Número:-2147202558
Mensaje:Attachment file size is too big.
Puede utilizar los siguientes ejemplos para comprobar el tamaño máximo de archivo:
El método GetFileColumnMaxSizeInKb
estático devuelve el valor MaxSizeInKB
para una columna de archivo.
/// <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.");
}
}
Más información:
Descargar archivos
Hay tres métodos diferentes de descargar archivos desde una columna de archivos:
- Usar mensajes de Dataverse disponibles tanto para el SDK Webcomo para la API web
- Descargar un archivo en una sola solicitud usando la API web
- Descargar el archivo en fragmentos utilizando la API web
Nota
Estos métodos también se pueden usar para descargar columnas de imágenes, pero existen algunas diferencias. Más información: Descargar imágenes
Para entornos local o cuando un entorno usa la Clave auto administrada (BYOK), el archivo no está en el almacenamiento de archivos. Cuando un archivo no está en el almacenamiento de archivos, no se admite la descarga en varios fragmentos. InitializeFileBlocksDownloadResponse ComplexType y la clase InitializeFileBlocksDownloadResponse tienen una propiedad IsChunkingSupported
que indica si el archivo se puede descargar en varios fragmentos o no. Si no se admite la fragmentación, configure BlockLength
en el tamaño del archivo.
Intentar descargar un fragmento parcial cuando IsChunkingSupported está establecido en falso dará como resultado este error:
Nombre: UploadingAndDownloadingInMultipleChunksNotSupported
Código: 0x80090017
Mensaje: Downloading in multiple chunks is not supported for the files stored in the database.
Usar mensajes de Dataverse para descargar un archivo
Puedes usar mensajes de Dataverse usando el SDK para .NET o API web. Descargar un archivo de esta manera requiere el uso de un conjunto de dos mensajes:
Publicación | Descripción |
---|---|
InitializeFileBlocksDownload |
Utilice este mensaje para indicar la columna desde la que desea descargar un archivo. Devuelve el tamaño del archivo en bytes y un token de continuación de archivo que puede usar para descargar el archivo en bloques usando el mensaje DownloadBlock . |
DownloadBlock |
Solicite el tamaño del bloque, el valor de desplazamiento y el token de continuación del archivo. |
Una vez que haya descargado todos los bloques, debe unirlos para crear el archivo descargado completo.
Puede usar una función como la siguiente para descargar un archivo o imagen usando el SDK mediante las clases InitializeFileBlocksDownloadRequest y 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();
}
Más información:
Descargar un archivo en una sola solicitud usando la API web
El siguiente ejemplo descarga un archivo de texto llamado 4094kb.txt
de la columna del archivo denominada sample_filecolumn
en la tabla account
para un registro con accountid
igual a <accountid>
.
Solicitud:
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
Respuesta:
La respuesta incluye los siguientes encabezados.
Encabezado | Descripción |
---|---|
x-ms-file-size |
Tamaño de archivo en bytes. |
x-ms-file-name |
El nombre del archivo. |
mimetype |
El tipo MIME del archivo. |
Access-Control-Expose-Headers | Indica que los valores de encabezado x-ms-file-size , x-ms-file-name y mimetype deben estar disponibles para los scripts que se ejecutan en el navegador, en respuesta a una solicitud de origen cruzado. |
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. >
Descargar el archivo en fragmentos utilizando la API web
Nota
El siguiente ejemplo es para casos en los que IsChunkingSupported
se establece en verdadero. Si es falso, utilice Descargar un archivo en una sola solicitud utilizando la API web.
Para descargar su archivo en fragmentos usando la API web, use el siguiente conjunto de solicitudes.
El siguiente ejemplo descarga un archivo PDF llamado 25mb.pdf
a la columna del archivo denominada sample_filecolumn
en la tabla account
para un registro con accountid
igual a <accountid>
.
Solicitud:
Use el encabezado Range para especificar el número de bytes a devolver usando este formato:
<unit>=<range-start>-<range-end>
Donde unit
es bytes y range-start
para la primera solicitud es 0
.
No sabrá cuántas iteraciones se requieren para descargar el archivo completo hasta que obtenga la primera respuesta donde el encabezado de respuesta x-ms-file-size
le indica el tamaño del archivo.
Mientras que <range-start>
sea más pequeño que el tamaño total del archivo, para cada solicitud subsiguiente incremente los valores <range-start>
y <range-end>
para solicitar el siguiente fragmento del archivo.
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
Respuesta:
La respuesta incluye los siguientes encabezados:
Encabezado | Descripción |
---|---|
x-ms-file-size |
Tamaño de archivo en bytes. |
x-ms-file-name |
El nombre del archivo. |
x-ms-chunk-size |
Proporciona un tamaño de fragmento recomendado en bytes. |
mimetype |
El tipo MIME del archivo. |
Access-Control-Expose-Headers | Indica que los valores de encabezado x-ms-file-size , x-ms-file-name , x-ms-chunk-size y mimetype deben estar disponibles para los scripts que se ejecutan en el navegador, en respuesta a una solicitud de origen cruzado. |
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 archivos
Hay dos formas diferentes de eliminar archivos en una columna de archivos:
- Usar los mensajes de Dataverse
DeleteFile
disponibles tanto para el SDK Webcomo para la API web - Enviar una solicitud DELETE utilizando la API web a la columna de archivo del registro.
Usar el mensaje DeleteFile
Utilizando el identificador único devuelto por CommitFileBlocksUploadResponse.FileId
o recuperado de la columna como se describe en Comportamiento al recuperar, puede eliminar el archivo usando el mensaje DeleteFile
.
Puede usar una función como la siguiente para eliminar un archivo usando el identificador único mediante la Clase DeleteFileRequest.
static Guid DeleteFile(IOrganizationService service, Guid fileId)
{
DeleteFileRequest deleteFileRequest = new()
{
FileId = fileId
};
service.Execute(deleteFileRequest);
}
Enviar solicitud DELETE a la columna del archivo
Con la API web, puede eliminar un archivo enviando una solicitud DELETE
a la ubicación del recurso de archivo.
El siguiente ejemplo elimina datos de un archivo para una columna llamadda sample_filecolumn
en la tabla account
para un registro con accountid
igual a <accountid>
.
Solicitud:
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
Respuesta:
HTTP/1.1 204 NoContent
OData-Version: 4.0
Más información: Eliminar un solo valor de propiedad
Consulte también
Información general sobre imágenes y archivos
Tipos de datos de columna > Columnas de archivo
Trabajar con definiciones de columna de archivo mediante código
Ejemplo: Operaciones de archivo usando la SDK de Dataverse para .NET
Ejemplo: Operaciones de archivo usando la API web de Dataverse
Nota
¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)
La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).