0

When I try the following code with a postback the file download takes place normally:

FileInfo file = new FileInfo("C:\\a.txt");
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "text/plain";
Response.TransmitFile(file.FullName);
Response.End();

However if I put the above code inside a public static web method and call it with AJAX I get error, like "Process was being aborted".(Of course to get the current response I write HttpContext.Current.Response) This makes me think that the nature of the two responses are different. My question is if they are different, then what exactly is/are different? Is there a way to achieve the same thing with AJAX?

Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206

2 Answers2

1

The browser isn't going to receive the file via an XHR (Ajax) call. You will want to return the file location and then send the browser to that file via window.location or window.open.

Edit: Here's a Web Forms sample. My Web Forms skills are a little rusty since I've been using MVC now; the syntax is off the top of my head so you might need to fix it up a little.

ASPX Page

<div id="whateverIsContainingYourDialog">
    <form id="mikeJMIsAwesome" runat="server">
        <asp:TextBox id="firstName" runat="server" />
        <asp:TextBox id="lastName" runat="server" />

        <asp:Button id="submit" runat="server" />
    </form>
</div>

Server Side Code

protected void submit_OnClick(object sender, EventArgs e) {
    //Your logic for creating the file and the code you originally posted for serving the file.
}
Justin Helgerson
  • 24,900
  • 17
  • 97
  • 124
  • @MikeJM - If you have the code working via a POST request, why don't you just take that approach? My biggest question is why are you trying to use Ajax for this? What does using Ajax give you that a regular ol' POST request does not? – Justin Helgerson Dec 20 '12 at 17:31
  • OK, let me explain why. I have a jQueryUI dialog inside which I have some HTML content. After user makes his/her choice and enters some input, they press OK button. That ok button goes to server and creates a file based on the user input and finally the user should be able to download that file. Now, how do I make a postback inside this dialog? I do not see any other way of communicating with the server else than AJAX. I might miss something. Please let me know if there's an easy solution to this. – Mikayil Abdullayev Dec 20 '12 at 17:35
  • @MikeJM - I think there's an easier way to do this. Inside of your jQuery UI Dialog create a `form` where the action is `POST`ing to the page of your choice. On the server-side, take the user input and do what you need to do to create the file. From there, use the code you provided in your post to provide the response to the client and you should be all set (the code you posted looks just fine to me). – Justin Helgerson Dec 20 '12 at 17:40
  • Can you help with the "create a form where the action is POSTing to the page of your choice.". Because I have no idea how to do it. Sorry for taking your time.Maybe add this to your answer.I've been having this headache for more than a week now. – Mikayil Abdullayev Dec 20 '12 at 17:44
  • @MikeJM - Sure. Are you using ASP.NET MVC or ASP.NET Web Forms? I presume you're using Web Forms. – Justin Helgerson Dec 20 '12 at 17:44
1

What Ek0nomik said, file downloads are handled by the browser and cannot be handled through Javascript. The responses are both identical they are are both just http responses - you can verify this with fiddler or another tool (http://www.fiddler2.com/fiddler2/).

Essentially you ajax method will not be able to handle receiving a file and will certainly not have the permissions to assemble it and store it on you hard drive.

You can 'fake' a user clicking on a link using some Javascript.

Please check this similar question for an answer. I've pasted the answer from it below.

starting file download with JavaScript

We do it that way: First add this script.

<script type="text/javascript">
function populateIframe(id,path) 
{
    var ifrm = document.getElementById(id);
    ifrm.src = "download.php?path="+path;
}
</script>

Place this where you want the download button(here we use just a link):

<iframe id="frame1" style="display:none"></iframe>
<a href="javascript:populateIframe('frame1','<?php echo $path; ?>')">download</a>
The file 'download.php' (needs to be put on your server) simply contains:

<?php 
   header("Content-Type: application/octet-stream");
   header("Content-Disposition: attachment; filename=".$_GET['path']);
   readfile($_GET['path']);
?>

So when you click the link, the hidden iframe then gets/opens the sourcefile 'download.php'. With the path as get parameter. We think this is the best solution!

Community
  • 1
  • 1
CountZero
  • 6,171
  • 3
  • 46
  • 59