Header Ads Widget

Download Multiple Files as a ZIP from Blob in D365FO Using X++ Code

 

In Dynamics 365 Finance and Operations (D365FO), you can easily download multiple files from Azure Blob storage and package them into a single ZIP file for the user. This article will guide you through the process of doing this with X++ code, ensuring the content is fresh, optimized for SEO, and follows best practices.

Overview

Often, businesses need to download multiple documents from cloud storage, such as invoices, reports, or other critical data, and share them in a compressed format for easy distribution. By using D365FO and Azure Blob storage, we can streamline this process with X++ code.

In this article, we'll cover:

  • How to download files from Blob storage.

  • How to create and send a ZIP file containing multiple files.

  • Code examples with improved variable names and readability.


Prerequisites

Before diving into the code, ensure you have:

  • Access to Azure Blob storage with appropriate connection strings.

  • The necessary permissions for reading from the Blob storage container.

  • Familiarity with D365FO development environment (X++).


Step 1: Downloading Files from Blob Storage

First, let's create a method to download a file from Azure Blob storage. This method will take the document type and file name as inputs, and return the file in a stream.

x++
public static System.IO.Stream downloadFileFromBlob(DocType _docType, FileName _fileName) { FileName folderName = BlobHelper::getBlobFolder(_docType); try { // Parse Azure Storage connection string CloudStorageAccount cloudStorageAccount = CloudStorageAccount::Parse(AzureStorageConnectionString); // Get reference to the Blob client CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient(); // Get reference to the Blob container CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(folderName); // Get reference to the specific Blob (file) CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(_fileName); // Prepare a memory stream to store the file content System.IO.Stream fileStream = new System.IO.MemoryStream(); // Download file content into the stream cloudBlockBlob.DownloadToStream(fileStream, null, null, null); return fileStream; } catch { throw error(strFmt("Unable to download file: %1", _fileName)); } }

Explanation:

  • downloadFileFromBlob: Downloads the file from the specified Blob container and returns it as a memory stream. This stream will be used later to create ZIP entries.


Step 2: Creating a ZIP File with Multiple Files

Next, we will create the method that packages the downloaded files into a ZIP archive. The files will be selected from a multi-selection list and then added to a ZIP file, which will be sent to the user for download.

x++
private void downloadFilesAsZip() { SelectionHelper helper; DocHistoryTable docRecord; str zipFileName; str currentDate; // Initialize the selection helper to get selected documents helper = SelectionHelper::construct(); helper.parmDatasource(DocHistoryTable_DS); // Get the first selected document docRecord = helper.getFirst(); // Generate a timestamp for the ZIP file name currentDate = today(); // Set the name for the ZIP file (based on user ID and current date) zipFileName = curUserId() + "_" + currentDate + ".zip"; using(System.IO.MemoryStream zipMemoryStream = new System.IO.MemoryStream()) { // Create a new ZIP archive in memory using (System.IO.Compression.ZipArchive zipArchive = new System.IO.Compression.ZipArchive(zipMemoryStream, System.IO.Compression.ZipArchiveMode::Create, true)) { // Loop through all the selected documents while (docRecord) { // Create a new file entry in the ZIP archive System.IO.Compression.ZipArchiveEntry zipEntry = zipArchive.CreateEntry(docRecord.FileName); // Open the entry for writing the file's contents using (System.IO.Stream zipEntryStream = zipEntry.Open()) { // Download the document from Blob storage System.IO.Stream fileStream = downloadFileFromBlob(docRecord.DocType, docRecord.FileName); // Reset the file stream position to the start fileStream.Seek(0, System.IO.SeekOrigin::Begin); // Copy the file content into the ZIP entry fileStream.CopyTo(zipEntryStream); fileStream.Close(); } // Move to the next document record docRecord = helper.getNext(); } } // Send the ZIP file to the user File::SendFileToUser(zipMemoryStream, zipFileName); } // Refresh the data source after the download DocHistoryTable_DS.refresh(); }

Explanation:

  • downloadFilesAsZip: This method creates a ZIP file with the selected documents. It uses a MemoryStream to generate the ZIP archive in memory and sends it to the user.

  • zipEntry: A new entry is created in the ZIP file for each selected document.

  • fileStream.CopyTo(zipEntryStream): This line ensures that the file's content is copied to the corresponding entry in the ZIP file.


Best Practices and Considerations

  1. Memory Management: Since ZIP files can get large depending on the number of documents, it's crucial to manage memory efficiently. Consider implementing file streaming if dealing with large files to avoid memory overflows.

  2. Error Handling: Ensure robust error handling is implemented when interacting with cloud storage. This includes validating that files exist in the container and handling network issues gracefully.

  3. Security: Ensure that the appropriate permissions are granted for accessing and downloading files from Blob storage. Implement proper security measures, such as user authentication and authorization.

  4. Asynchronous Processing: For large numbers of files, consider implementing asynchronous processing to improve user experience and prevent timeouts.


Conclusion

By following the steps outlined in this article, you can easily download multiple files from Azure Blob storage, package them into a ZIP archive, and send them to users in Dynamics 365 Finance and Operations. This method enhances user experience by simplifying the process of downloading multiple files in one go, making it efficient and easy to manage.

Post a Comment

0 Comments