0

I'm trying to provide a browser user the ability to select a file from a list an download a file back to the user as a file download.

My JavaScript looks like this:

$scope.getFile = function (podUri, podName) {
    $http.get('api/getDharmaPod', { params: { containerName: $scope.selectedContainer, podName: podName } })
    .success(function (data, status, headers, config) {
        $("#audio").text("Got file: ");
    })
  .error(function (data, status, headers, config) {
            alert("got an error:" + status);
        });
};

I've also tried the following that I found on stackOverflow

$scope.getFile = function (podUri, podName) {
    $http({
        method: 'GET',
        params: { containerName: $scope.selectedContainer, podName: podName },
        cache: false,
        url: 'api/getDharmaPod',
        headers: {
            'Content-Type': 'audio/mpeg; charset=utf-8'
        }
    }).success(function (data, status) {
        console.log(status); 
    }).error(function (data, status) {
        alert("got an error:" + status);
    });
};

But the result is the same: the browser silently receives the server's transmission and doesn't offer to save it anywhere.

My MVC controller method looks like this:

    [HttpGet, Route("api/getDharmaPod")]
    public async Task<HttpResponse> GetDharmaPod(string containerName, string podName)
    {
        var dharmaBlob = AzureStorageAccess.GetBlob(containerName, podName);
        MemoryStream memStream = new MemoryStream();
        dharmaBlob.DownloadToStream(memStream);
        Response.ContentType = "audio/mpeg";
        await Response.SendAsync(memStream.ToArray());
        return null;
    }

I've also tried:

[HttpGet, Route("api/getDharmaPod")]
public FileResult GetDharmaPod(string containerName, string podName)
{
    var dharmaBlob = AzureStorageAccess.GetBlob(containerName, podName);
    MemoryStream memStream = new MemoryStream();
    dharmaBlob.DownloadToStream(memStream);
    Response.ContentType = "audio/mpeg";
    return File(memStream.ToArray(), "audio/mpeg", podName);
}

Again the browser receives the data but doesn't see it as a file to be stored. It just receives it into a variable. I'd want it to see it as a download and save it to the download file.

I'm not sure if I'm sending it incorrectly or receiving it incorrectly or both :-(

Thanks for any guidance.

Community
  • 1
  • 1
Weej
  • 972
  • 2
  • 7
  • 24

1 Answers1

0

I've decided to go another way since I can't seem to find a solution.

My solution is to just download the file directly from the container using the blob's url. I've made it somewhat secure by generating a shared access key in my controller as follows:

public static string GetSharedAccessKey(string containerName)
{
    CloudStorageAccount storageAccount = GetAccount(_useDev);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference(containerName);
    SharedAccessBlobPolicy blobPolicy = new SharedAccessBlobPolicy
    {
        Permissions = SharedAccessBlobPermissions.Read,
        SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1)
    };
    return container.GetSharedAccessSignature(blobPolicy);
}

this returns an access key that can be appended to the 'a' tag's href link for the blob file that allows access for one hour.

I'm now getting a file that the browser is storing in the downloads directory as expected.

The result of allowing direct access to the storage account is also more efficient for the server-side app.

Weej
  • 972
  • 2
  • 7
  • 24