1
votes

Hello I am having issues downloading a file from an ASP.NET Core Razor page using an AJAX Post. What I want to do seems repetitively simple but has proved to be a real pain.

  1. I do not want to store the file on the server but I am alright with TempData and a guid if needed.

  2. I want to do a ajax post because I am sending data from the client to build the file.

  3. Data sent to server will be encrypted into a string and that will be the contents of the file. (Note: Encryption is already working)

  4. I want the file to download as my own extension *.dat.

Here is my asp.net core razor post method.

public IActionResult OnPostDownloadEncryptedFile([FromBody] List<FileData> fileData)
    {
        var response = ...THIS IS A REST WEB API CALL ASYNC I am calling .Result
       
        var byteArray = Encoding.ASCII.GetBytes(response.EncryptedData);
        var stream = new MemoryStream(byteArray);

        return this.File(stream, System.Net.Mime.MediaTypeNames.Application.Octet, "myfile.dat");
    }

Here is my Ajax post code:

$.ajax({
        type: "POST",
        url: "/MySite/MyPage?handler=DownloadEncryptedFile",
        beforeSend: function (xhr) {
            xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
        },
        data: JSON.stringify(myData),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            
        },
        error: function (response) {
            alert(response);
        }
    });

I realize that the ajax post is most likely incomplete and wrong not quite sure how to fix I have seen others using window.location but I am not sure how that works. Since when debugging I never have been able to get into the ajax post success function.

Any help would be greatly appreciated.

1

1 Answers

0
votes

I got it working but I feel like its a terrible implementation.

Here is what I did:

public IActionResult OnPostEncryptFileData([FromBody] List<FileDataItem> fileData)
    {
        var response = this.restEndpoint.EncryptFileData(
            new FileDataEncryptionRequest()
            {
                FileDataListItems = new FileDataList() { FileDataItems = fileData.ToList() }
            }).Result;

        return new JsonResult(response.EncryptedData);
    }

    public FileResult OnGetDownloadEncryptedFile(string data)
    {
        var byteArray = Encoding.ASCII.GetBytes(data);
        return this.File(byteArray, "text/plain", "test.dat");
    }

The Ajax post:

$.ajax({
        type: "POST",
        url: "/MySite/MyPage?handler=EncryptFileData",
        beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); },
        data: JSON.stringify(fileData),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            alert(response);
            window.location = "/MySite/MyPage?handler=DownloadEncryptedFile&data=" + response;
        },
        failure: function (response) {
            alert(response);
        }
    });

Would love to hear some better solutions.