-2

I want to download multiple types of files using AJAX.

I decided to generate a get requests with file name as query string using AJAX and get the response as base64 string and then convert it to blob object and download/save it using hyperlink a tag along with download attribute.

Kindly help me, how to use the optimized way/code to convert file to base64 string and then revert the base64 string to blob?

Imran Rafique
  • 329
  • 3
  • 10
  • 2
    Possible duplicate of [C# Converting file into Base64String and back again](http://stackoverflow.com/questions/25919387/c-sharp-converting-file-into-base64string-and-back-again) – CodeCaster Feb 11 '16 at 07:52
  • [Create a file in memory for user to download, not through server](http://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server) – CodeCaster Feb 11 '16 at 07:53
  • my question is not similar to both mentioned above, so kindly do not mark it as duplicate. – Imran Rafique Feb 11 '16 at 10:29
  • It most certainly is. You're not the first who wants to do this, so read [ask] and share your research. – CodeCaster Feb 11 '16 at 10:30

2 Answers2

1

ASP.Net httpHandler code is here:

Imports System
Imports System.Web
Imports System.IO
Public Class FileDownload : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    Dim Request As HttpRequest = context.Request
    Dim Response As HttpResponse = context.Response
    Dim serverFile As String = Request.QueryString("filename")
    Dim filePath As String = String.Empty
    filePath = context.Server.MapPath("~") & "\" & serverFile
    Dim file As New System.IO.FileInfo(filePath)
    Try
        If (file.Exists) Then
            Response.Clear()
            Response.ClearContent()
            Using reader As New FileStream(filePath, FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
                Dim buffer As Byte() = New Byte(reader.Length - 1) {}
                reader.Read(buffer, 0, CInt(reader.Length))
                Response.Write(Convert.ToBase64String(buffer))
            End Using
            Response.Flush()
            Response.End()
        Else
            Response.Write("File Not Found!")
            Response.StatusCode = 500
        End If
    Catch ex As Exception
        Response.Write(ex.ToString)
        Response.StatusCode = 500
        context.ApplicationInstance.CompleteRequest()
    End Try
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
    Get
        Return False
    End Get
End Property
End Class

Javascript function called with httphadler's application path as url and client side file name as filename

function downloadFileByAjax(filename, url) {
$.ajax({
    type: 'GET',
    url: url,
    responseType: 'arraybuffer',
    downloadid: filename,
    success: function (result, status, xhr) {
        var octetStreamMime = 'application/octet-stream';
        var filename = this.downloadid;
        var contentType = xhr.getResponseHeader('content-type') || octetStreamMime;
        var a = document.createElement('a');
        var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
        if (urlCreator && window.Blob && ('download' in a) && window.atob) {
            var blob = base64ToBlob(result, contentType);
            var url = window.URL.createObjectURL(blob);
            a.setAttribute('href', url);
            a.setAttribute("download", filename);
            var event = document.createEvent('MouseEvents');
            event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
            a.dispatchEvent(event);
            //window.URL.revokeObjectURL(url);
        }
    },
    error: function (xhr, msg, error) {
        //console.log(xhr, msg, error);
        //console.log(xhr.responseText);
        console.log(msg);
    },
    complete: function (xhr, status) {
        //console.log('completed');
    }
});
}
function base64ToBlob(base64, mimetype, slicesize) {
if (!window.atob || !window.Uint8Array) {
    console.log('The current browser doesnot have the atob function. Cannot continue');
    return null;
}
mimetype = mimetype || '';
slicesize = slicesize || 512;
var bytechars = atob(base64);
var bytearrays = [];
for (var offset = 0; offset < bytechars.length; offset += slicesize) {
    var slice = bytechars.slice(offset, offset + slicesize);
    var bytenums = new Array(slice.length);
    for (var i = 0; i < slice.length; i++) {
        bytenums[i] = slice.charCodeAt(i);
    }
    var bytearray = new Uint8Array(bytenums);
    bytearrays[bytearrays.length] = bytearray;
}
return new Blob(bytearrays, { type: mimetype });
}
Imran Rafique
  • 329
  • 3
  • 10
0

To convert a file to base64 string use the following code

string data;
using (FileStream fs = new FileStream(dir + fileName, FileMode.Open, FileAccess.Read)) {
    byte[] buffer = new byte[fs.Length];
    fs.Read(buffer, 0, (int)fs.Length);
    data = Convert.ToBase64String(buffer);
    fs.Close();
}
return data;

In the success function of the ajax call convert the string to blob using the following code

var byteCharacters = atob(data);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
  byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob = null;
blob = new Blob([byteArray], { type: 'text/plain' });
blob = new Blob([byteArray], { type: 'application/pdf;base64' });
var blobUrl = URL.createObjectURL(blob);

Depending upon the file format you can specify the type attribute for the blob and then assign the blobUrl as the source to your anchor tag

Yash Vora
  • 61
  • 3