www.dextsolution.com
DEXTUPLOAD
X5
Product description > Compress-download (ASP.NET)

# Compress-download (ASP.NET)

Starting with DEXTUploadX5 version 1.3.0.0, we support compressed downloads. Compressed downloads are downloads that combine the downloads into a single compressed file.

One thing to keep in mind is that the server is responsible for compressing files, not the ability to compress files in the DEXTUploadX5 product. DEXTUploadX5 passes the value of the vindex property to download to the server. The server selects a target to be compressed with a vindex value and generates a compressed file. When the compressed file is created, the path to download the file is returned to the client, and DEXTUploadX5 receives the download path and requests it again.

The server must have the ability to compress files, which can be implemented using several compression libraries, but in the case of ASP.NET, you can compress files using the ZipArchive class, which is supported by the .NET Framework 4.5.

Registering item to be downloaded

  You must register the item to be downloaded as a virtual file.

  A virtual file is a fake file that does not exist on the user's local PC and has no substance. That is, the file is not a file to be uploaded because it is a file that does not exist locally. In general, virtual files are used to keep information about already uploaded files. (An indication that the file exists on the server)

  To register a virtual file, use the addVirtualFile function or the addVirtualFileList function.

  - vindex: The unique key that distinguishes a virtual file. It can be in any format, but it should not be duplicated. (Required field)
  - name: The name of the virtual file. (Required field)
  - size: The size of the virtual file, in bytes. (Required field)
  - lock: If the lock status is true, the file can not be deleted.

      var dx = dx5.get(id);
      // When registering individually
      dx.addVirtualFile({ vindex: "IDX0001", name: "virtual_file.txt", size: 12345 });
      dx.addVirtualFile({ vindex: "IDX0002", name: "virtual_file_lock.txt", size: 45678, lock: true });
      dx.addVirtualFile({ vindex: "IDX0003", name: "cosmos.jpg", size: 195779 });

      // When adding at once
      dx.addVirtualFileList([
        { vindex: "IDX0001", name: "virtual_file.txt", size: 12345 },
        { vindex: "IDX0002", name: "virtual_file_lock.txt", size: 45678, lock: true },
        { vindex: "IDX0003", name: "cosmos.jpg", size: 195779 }
      ]);

  Unlike single/multiple file(s) downloads, you do not need to set the url (or downUrl) property when using Compress-download. Compress-download requires only one address that is responsible for compressing files and returning its download path. Therefore, the url (or downUrl) property that you set for each virtual file has no effect on Compress-download.

Setting the compression path

  After registering virtual files, you need to set the path for compression. The compression path can only be registered once using the setCompressURL method.

  The path must be a web URL that starts with a schema (http, https).

      function onDX5Created(id) {
        var dx = dx5.get(id);

        dx.addVirtualFile({ vindex: "IDX0001", name: "virtual_file.txt", size: 12345 });
        ...
        dx.addVirtualFile({ vindex: "IDX0005", name: "cosmos (empty) 195779.jpg", size: 195779 });

        // Set the path to process the compression.
        dx.setCompressURL("http://domain/path/compress.ashx");
      }

Setting button events

  Once you have set up virtual files and the compression path, you can start the Compress-download using the downloadCompressed method.

      <button type="button" onclick="compress('component-id');">Compress & Download</button>
      <script>
      function compress(id) {
        // Perform to download after compressing according to the flag value.
        // AUTO: Compress the all virtual file.
        // SELECTED: Compress the all selected virtual file.
        // CHECKED: Compress the all checked virtual file.
        dx5.get(id).downloadCompressed("AUTO");
      }
      </script>

  It also provides automatic binding at component loading time without using complex scripts.

      <button type="button" id="btn-compress-auto">Compress & Download</button>
      <button type="button" id="btn-compress-selected">Compress selected & Download</button>
      <button type="button" id="btn-compress-checked">Compress checked & Download</button>
      <script>
        dx5.create({
          ...,
          // The compressing and downloading function automatically sets when the component is created.
          btnDownloadCompressedAuto: "btn-compress-auto",
          btnDownloadCompressedSelected: "btn-compress-selected",
          btnDownloadCompressedChecked: "btn-compress-checked"
        });
      </script>

  The automatic binding functionality is very convenient, but it may not be suitable for implementing complex functions.

Server-Side processing (ASP.NET)

  You can use the ZipArchive class in compress.ashx to handle compression.

  When DEXTUploadX5 calls the downloadCompressed method, it creates a list string with a comma (,) character delimiter for the vindex property values and submits this value to POST form data named 'DEXTUploadX5_VIndexes'.

      // DEXTUploadX5 is a POST method that sends a value (a list of vindexes) to the server named 'DEXTUploadX5_VIndexes'.
      var data = context.Request.Form["DEXTUploadX5_VIndexes"] ?? string.Empty;
      var vindexes = data.Split(',');
      var targets = new List<string>();

      foreach (string index in vindexes)
      {
          if (index.Equals("IDX0003")) targets.Add(context.Server.MapPath("~/files/attach/bridge_509147.jpg"));
          else if (index.Equals("IDX0004")) targets.Add(context.Server.MapPath("~/files/attach/beach_239826.jpg"));
          else if (index.Equals("IDX0005")) targets.Add(context.Server.MapPath("~/files/attach/cosmos (empty) 195779.jpg"));
      }

      var zipPath = Path.GetTempFileName();

      // Create a compressed file using ZipArchive, which is supported by .NET Framework 4.5.
      using (var fs = new FileStream(zipPath, FileMode.Create))
      using (var za = new ZipArchive(fs, ZipArchiveMode.Create, false, System.Text.Encoding.UTF8))
      {
          foreach (string path in targets)
          {
              za.CreateEntryFromFile(path, Path.GetFileName(path));
          }
      }

      // In real life, not in the example , you have to handle the path of the compressed file in a handler (zip-download.ashx) that actually needs to be downloaded using a different way of storing such as session or database .
      // The FileRepository and FileEntity classes have been created to aid for understanding this example.

      FileRepository.Clear();
      var key = FileRepository.Add(new FileEntity {
          Path = zipPath,
          MimeType = "application/x-zip-compressed",
          FileName = string.Concat(Path.GetFileNameWithoutExtension(zipPath), ".zip")
      });

      // Create a handler path to download the compressed file.
      UriBuilder b = new UriBuilder(context.Request.Url);
      b.Path = VirtualPathUtility.ToAbsolute("~/download/zip-download.ashx");
      b.Query = string.Concat("key=", key);

      // The path to download the compressed file must be loaded in the response data and passed to the client.
      context.Response.ContentType = "text/plain";
      context.Response.Write(b.ToString());

  After compressing the target files, you need to download the compressed file. The value recorded in the response data is the server-side path for downloading the compressed file, which can be implemented in the following manner.

      var key = context.Request.QueryString["key"] ?? string.Empty;
      var entry = FileRepository.Get(key);

      if (entry != null)
      {
          // Perform the download using DEXTUpload.NET Professional.
          using (var dext = new FileDownload())
          {
              dext.Download(entry.Path, entry.FileName, new DownloadOption {
                  // After downloading the compressed file is to delete the file because it is pointless.
                  RemoveAfterDownloading = true,
                  // The compressed file does not use the client cache are created for every request.
                  UseClientCache = false,
                  // application/x-zip-compressed
                  MimeType = entry.MimeType
              });
          }
      }
      else
      {
          throw new HttpException(404, "The zip file not found.");
      }

Server-Side processing (ASP.NET MVC)

  It is assumed that the compression operation is requested at the following address.

      function onDX5Created(id) {
        var dx = dx5.get(id);

        dx.addVirtualFile({ vindex: "IDX0001", name: "virtual_file.txt", size: 12345 });
        ...
        dx.addVirtualFile({ vindex: "IDX0005", name: "cosmos (empty) 195779.jpg", size: 195779 });
        // Set the path to process the compression.
        dx.setCompressURL("http://domain/DownloadSample/Compress");
      }

  The server uses the ZipArchive class in the Compress method of the DownloadSampelController to handle the compression operation.

      [HttpPost]
      public ActionResult Compress([Bind(Prefix = "DEXTUploadX5_VIndexes")] string data)
      {
          var vindexes = data.Split(',');
          var targets = new List<string>();

          foreach (string index in vindexes)
          {
              if (index.Equals("IDX0003")) targets.Add(Server.MapPath("~/files/attach/bridge_509147.jpg"));
              else if (index.Equals("IDX0004")) targets.Add(Server.MapPath("~/files/attach/beach_239826.jpg"));
              else if (index.Equals("IDX0005")) targets.Add(Server.MapPath("~/files/attach/cosmos (empty) 195779.jpg"));
          }

          var zipPath = Path.GetTempFileName();

          // Create compressed files using ZipArchive, which is supported by .NET Framework 4.5.
          using (var fs = new FileStream(zipPath, FileMode.Create))
          using (var za = new ZipArchive(fs, ZipArchiveMode.Create, false, System.Text.Encoding.UTF8))
          {
              foreach (string path in targets)
              {
                  za.CreateEntryFromFile(path, Path.GetFileName(path));
              }
          }

          // In real life, not in the example, you should use a different storage method, such as a session or database, to handle the path of the compressed file in the path where you really need to perform the download.

          ...

          // The path to download the compressed file must be loaded in the response data and passed to the client.
          return Content(Url.Action("DownloadZip", new { id = key }), "text/plain", Encoding.UTF8);
      }

  After compressing the target files, you need to download the compressed file. The value recorded in the response data is the server-side path for downloading the compressed file, which can be implemented in the following manner.

      [HttpGet]
      public ActionResult DownloadZip(string id)
      {
          var entry = FileRepository.Get(id);

          if (entry == null)
          {
              throw new HttpException(404, "The zip file not found.");
          }
          else
          {
              return File(entry.Path, "application/x-zip-compressed", entry.FileName);
          }
      }

Limitations of Compress-download and Notices
  - DEXTUploadX5 supports a series of workflows for Compress-downloads, and does not have the ability to compress files on its own.

  - Compress-download has a process of compressing files on the server side. If the time required to compress a file is long, an unintended problem may occur.

    Compressing files is a task that consumes a lot of server resources (CPU, I/O), so if you have a large number of files that are large files or compressed files. Depending on the situation, it may take a long time to wait for the file compression process, which may lead to a problem of a session being disconnected or a serious problem that the service itself is stopped. Therefore, it is recommended to use the function after establishing policy for the Compress-download.

    The DEXTUploadNJ server component product used in the Java environment provides a class called CompressUtil for compression, which uses the Apache Commons Compress library. Refer to the DEXTUploadNJ product manual for details.

  - DEXTUploadX5 displays a progress window while compression is running on the server, but it does not provide its own progress window for the download process because it will switch to a single-file-download when downloading the compressed file.

  - If you perform a zip download in the macOS Safari browser, the download process may not be convenient due to the browser's pop-up blocking feature. Therefore, it is necessary to cancel the Safari setting which blocks the pop-up of the site that you want to service beforehand.

    Since the macOS Safari browser unzips the zip file by 'Open file safely' function after downloading the file, the zip file may not be downloaded as it is. If you want to prevent the zip file from being automatically unzipped, you can check the settings in the General tab of Safari Preferences.