Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extjs Ajax file download request C# MVC

I want client to download a file stored on my db when clicked a button. I send this ajax request and take it from the server side.

EXTJS:

downloadFile: function (a, b, c) {
    var feed_id =this.getMyfeedwindow().down('form').getComponent('FeedId').text;
    Ext.Ajax.request({
        url: '/Feed/Download',
        method: 'GET',
        params: {
            fileID: feed_id, //this.form.getComponent('file').value,
        },
        failure: function (response) {
            alert('failed  !');
        },
        success: function (response) {
            alert('success!');
        },
    });
},

then meet request with this code block.

C#:

 public void Download(string fileID){
    Response.ContentType = "application/force-download";
    Response.AddHeader("Content-Disposition", "attachment; Filename=\"Logo1.jpg\"");
    Response.BinaryWrite(data);
    Response.End();
 }

When I checked network with firebug, it seems my request returns successfully with these parameters.

Cache-Control   private
Content-Disposition attachment; filename="Logo1.jpg"
Content-Type    application/force-download
Date    Wed, 09 Jan 2013 12:51:54 GMT
Server  Microsoft-IIS/8.0
Transfer-Encoding   chunked
X-AspNet-Version    4.0.30319
X-AspNetMvc-Version 4.0
X-Powered-By    ASP.NET
X-SourceFiles   =?UTF-8?B?RTpcVXRrdUNhblxQcm9qZWN0c1xURlNcQlRPTVxCVE9NXEZlZWRcRG93bmxvYWQ=?=

Although it returns successful, download does not start. I read lots of questions and articles but most answers say adding force-download header solves the problem. Which point do I miss? Thanks.

like image 466
tkcn Avatar asked Jan 09 '13 13:01

tkcn


2 Answers

To handle a Download you should use one of the provided helper

  • System.Web.MVC.FilePathResult
  • System.Web.MVC.FileStreamResult
  • System.Web.MVC.FileContentResult

Most times I am using the System.Web.MVC.FileStreamResult mayself. Use it like

FileStreamResult result = new FileStreamResult(stream, contentType);
result.FileDownloadName = filename; // name of the downloaded file

Update Just some Infos based on your edit

You cannot start download using XHR request. But there are at least two ways how you can do it:

  • If the file-path is fix and you know it set top.location.href = "YourPath"; within the success handler of the ajax call. [Infos about top.location.href]
  • If you create the file on the fly and want to return it you should create a hidden iframe and inject a form into it that then execute the request.
like image 54
sra Avatar answered Oct 07 '22 20:10

sra


After some search, I found that location.href does the same thing and opens a download dialog box. Same headers should be added to the response coming from the server. However, I still don't know why the other approach does not work.

var feed_id = this.getMyfeedwindow().down('form').getComponent('FeedId').text;
location.href = '/Feed/Download?fileID=' + feed_id;

this solved my problem.

like image 28
tkcn Avatar answered Oct 07 '22 20:10

tkcn