1

My Webapi creates dynamic zip file. I want to be able to download that file. At the moment i was trying to use breeze but seems its not possible with it.

I have made simple example which just open zip file from my hard disk and then i return binary content in my webapi.

public HttpResponseMessage GetFile()
    {
        var path = @"C:\myFolder\ myfile.zip";
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var stream = new FileStream(path, FileMode.Open);
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType =
            new MediaTypeHeaderValue("application/x-zip-compressed");
        result.Content.Headers.Add("content-disposition", "attachment; filename=sendMyFileToClient.zip");
        return result;
    }

Then in my viewmodel i use breeze to call this method in webapi

var query = EntityQuery.from("GetFile");
        manager.executeQuery(query).then(function () {
            alert("Downloaded file");
        }).fail(function () { alert("Not downloaded"); });

Can someone tell if i cant do it in breeze, then do let me know if i can use ajax request to download or some other way? I cant find much on google.

James
  • 1,827
  • 5
  • 39
  • 69

2 Answers2

0

Breeze doesn't know what to do with your binary data, so it can't be much help. And you can't download and save files using JavaScript, because the browser's sandboxing doesn't allow JavaScript to access the file system.

So fundamentally, you need to set window.location to the URL of your server file/resource so the browser will download it and let the user save it. To preserve your SPA's single page, set the window.location of an iframe instead of the main window.

There are some other subtleties to consider, especially around error handling. Consider using something like the jQuery File Download Plugin as mentioned in this SO answer.

Community
  • 1
  • 1
Steve Schmitt
  • 3,124
  • 12
  • 14
  • My problem is that zip file is created in memory – James Sep 09 '14 at 10:12
  • Can you remove your answer as i have posted new question http://stackoverflow.com/questions/25747016/getting-damaged-zip-file-after-downloading Actually i want to delete this question – James Sep 09 '14 at 14:21
0

I found this question since I too 1) wanted to download a file from the server, 2) the file is in memory on the server and 3) I'm using breeze. And, I agree with Mr. Schmitt that breeze cannot do it. It seems to only be able to return a list of objects (records) -- which makes sense for breeze ... being for data access.

And, like me, I think you want to know how to download a file with or without breeze. I'm not familiar with web communication other than via breeze. I wanted to know how to download a file to a client that so far accesses data via breeze and from a server that so far only accepts queries from breeze. I didn't know whether the client and server were locked into breeze access. Since the answer seems to be that it's not, I feel rather naive.

The answer to how you download a file for a breeze client/server is: don't use breeze! Use some mechanism outside of the breeze ecosystem. I suppose to a seasoned web developer that is probably obvious, but it's not to me who has managed to remain rather ignorant of web technologies for the first 25 years of my career.

I don't know whether this answers your question. At least this might be useful to others who come across this question.

As for how you download a file, I'm guessing there are zillions of SO questions, blog posts and articles about that. But, I'll share my solution that I came up with ... FWIW.

Server code:

[HttpPost]
public HttpResponseMessage RelatedRegistrationsFromRegistration()
{
    var httpContent = new ByteArrayContent(...);
    httpContent.Headers.ContentType = new MediaTypeHeaderValue("Application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    httpContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "Related Registrations.xlsx"
    };
    return new HttpResponseMessage(HttpStatusCode.OK) { Content = httpContent };
}

Client code using angular's $http communcation service:

this.downloadFromUrl = function (url, refs) {
    $http({
        method: 'POST',
        url: url,
        data: serializeData({ 'refs': refs }),
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        responseType: 'arraybuffer'
    }).success(function (data, status, headers) {
        var filename = headers('content-disposition').split('=')[1].replace(';', '');
        var blob = new Blob([data], { type: headers('content-type') });
        if (navigator.msSaveBlob) {
            navigator.msSaveBlob(blob, filename);
        } else {
            var link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.setAttribute('download', filename);
            link.click();
            link.remove();
        }
    }).error(function () {
        alert('Error');
    });
}
steve
  • 1,021
  • 1
  • 14
  • 29