Today's pattern is not a pattern but a "cookbook" that shows how to use the FileManagement library to download multiple files as a .zip file through Microsoft Dynamics NAV in a way that works on all types of clients.
The goal of this pattern is to enable the users to download multiple files as a zip file instead of downloading one by one. On the Microsoft Dynamics NAV Web client, this is the preferred way of delivering multiple files since it is one of the web patterns and we cannot use the File Management codeunit to place files silently on the machine.
When generating reports that consists of multiple, and usually an unknown number of files, the developer will have to handle the download which also depends on the client the user is on. The problem is that the Microsoft Dynamics NAV Windows client has access to the user’s file system, whereas the web client does not. Following web guidelines, and the fact that client-side .NET is not available in Web client, you can’t initiate multiple downloads which requires the developer respond to the type of client. In some browsers it is possible to download files one-by-one in the Web client by using a confirm dialog, however this is a hack and should not be used.
To solve this problem, a generic download mechanism is used that is client dependent event when multiple files need to be downloaded. For the Web client, the files are compressed using ZIP, and for the Windows client the files are downloaded directly to the file system.
The pattern is usable for all objects that output multiple files and is available in both Windows client and Web client.
The pattern consists of two steps: 1) Gathering the files and 2) downloading the file(s)
For first step consists of a loop that goes through the files that needs to be downloaded. If it is on the Web client, the files are added to a ZIP archive server-side using a naming convention defined by the integration function GetSeriesFileName. This function takes a filename and number, and transforms it to unique names following a meaningful deterministic pattern e.g. prepend an integer before the file extension. The same function is used when the temporary files are created server side, so the files can be found deterministically later. This removes the need for storing filenames and consequently allows an arbitrary number of files. The second integration function: GetTotalNumberOfFiles, returns the total number of files generated during the data processing and makes the pattern able to handle an arbitrary number of files.
The second step is the actually download of file(s). For the Web client this consists of closing the ZIP achieve and downloading via the standard download handler that works in the Web client. For the Win client, the files are saved directly to the client during the first step.
Code 1: File loop shows an example implementation of this pattern. ServerFileName is generated at the beginning of the report/codeunit, and is the base for GetSeriesFilename. The file that is actually written to during data processing is stored in another variable which holds the output from GetSeriesFilename on the current file number. Note; the example code will only create a ZIP file if there in fact are multiple files to be downloaded.
Martin Dam at Microsoft Development Center Copenhagen