Downloading a file saved to a site's root directory

Discussion in 'Site Programming, Development and Design' started by fssFuller, Jul 30, 2019.

  1. I generate an excel spreadsheet in my ASP.Net Core web application that gets saved to the website's root directory on WinHost.

    But when I try to access the generated file (that I confirmed does exist on the server) I get a "HTTP Error 404.0 - Not Found".

    After researching the error, I found that it's possibly a misnomer, and it's a possible authorization issue when I try to download the file through my application via a FileStream.

    I read a thread that said that I could possibly get around the issue by changing the Trust Level to "full" by adding the following to my web.config:

    <configuration>
    <system.web>
    <trust level="Full" />
    </system.web>
    </configuration>

    However, my config is generated by ASP.Net Core and is a system.webServer instead of system.web and I can't currently find a way to do the same in my case.

    Is there a way around this? Am I way off the mark?
     
  2. ComputerMan

    ComputerMan Winhost Staff

    The 404 error means that the file is not there. You have also confirmed that the file didn't get saved too. Correct?

    Did you site produce any error messages after you created the excel spreadsheet?

    Can you PM me your domain name of your site account? I want to check your permissions.
     
  3. I thought the generation method might have been the issue, I FTP'd to the site and see the file exists. I thought it might be a race condition, as well, but when I recall the same URL to initiate the download I get the same 404 error.

    I'm not seeing a way to send a private message to you. How would I go about doing that?
     
  4. After doing some more digging I have come to realize that the function I'm trying to call is not being found and not the file itself.

    I successfully create the file and save it to the correct site, and the function I use isn't found when I attempt to download it.

    Here's how I am trying to kickoff the download via Javascript:

    function exportGrid(e) {
    $.get('@Url.Action("ExportPurifications", "Purification")', null, function (response) {
    window.location = '/Purification/DownloadExportedPurifications?fullName=' + response.FullName + '&filename=' + response.FileName;
    });
    }

    It was the only way I could find that would dump the file into a download bar.

    This works on my localhost but when it tries to set the window.location on a hosted server it can't find the function DownloadExportedPurifications in the purification controller. I put logging in that location and it hit locally hosted but didn't when remotely hosted.

    Any suggestions on how to request the file properly from a remote server?
     
  5. Elshadriel

    Elshadriel Winhost Staff

    Depends on where you saved the file relative to the root of your account. I don't know the directory structure of your site, but you might want to use windows.location.hostname instead. See this.
     
    ComputerMan likes this.
  6. The function itself (DownloadExportedPurifications) wasn't being called so there was never an operation trying to access the file itself.

    After some digging I found a way around this.

    Instead of returning the file path and name from the function that generates the file I instead read the file in as bytes and converted it to base 64 instead. I then returned the resultant string:

    Byte[] bytes = System.IO.File.ReadAllBytes(filePath);
    string file64 = Convert.ToBase64String(bytes);
    return new JsonResult(file64);

    I then created a javascript function that set that string to a blob, created an invisible a href tag that I connected the blob to, and manually clicked the hyperlink to initiate the download:

    $.get('@Url.Action("ExportPurifications", "Purification")', null, function (response) {
    downloadExcelReport("Exported_Purifications.xlsx", response);
    });

    function downloadExcelReport(filename, base64String) {
    var data = atob(base64String);
    var ab = s2ab(data); // from example above
    var blob = new Blob([ab], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' });

    var element = document.createElement('a');
    element.setAttribute('href', window.URL.createObjectURL(blob));
    element.setAttribute('download', filename);

    element.style.display = 'none';
    document.body.appendChild(element);

    element.click();

    document.body.removeChild(element);
    }

    function s2ab(s) {
    var buf = new ArrayBuffer(s.length);
    var view = new Uint8Array(buf);
    for (var i=0; i!=s.length; ++i) view = s.charCodeAt(i) & 0xFF;
    return buf;
    }

    That allowed me to download the server generated file. Thanks for your help ComputerMan and Elshadriel.

    StackExchange Resource that facilitated this solution: https://stackoverflow.com/questions/34993292/how-to-save-xlsx-data-to-file-as-a-blob
     
    Elshadriel and ComputerMan like this.

Share This Page