5

I am having to code up a button which, onclick, downloads a csv file onto the client's computer (this is a web app)

So, did some research, pulled all strings together, go figure, its not working.

I am trying to get this for now:

    protected void btnDownload_onClick(object sender, EventArgs e)
    {
        Response.Clear(); 
        Response.AddHeader("content-disposition", "attachment; filename=tmp.csv");
        Response.ContentType = "text/csv";
        Response.Write("one,two,three,four,five");
        Response.End();
    }

according to a blog that came up on google, that's all I need to get generate that csv an download it.

only, its not working and I cant figure out what's wrong with it.

1) firebug inspection: response is EMPTY.
2) VS Debugging, strangely stops after the line Response.End() and complaints that it cant find content.

Am I missing something? Thanks much. very much.

Edit: I just realized something, this is a child page and there is an update panel in the master page. Can this be the cause of the problem? if so, how can I cancel the ajax postback just for this child page?

LocustHorde
  • 6,361
  • 16
  • 65
  • 94
  • 1
    Does it not work in any major browser? – keyboardP Jun 23 '11 at 17:24
  • It's supposed to stop after response.end. Which browser are you having a problem with? Have you tried loading it in something other than firefox? Also, have you looked in your firefox Downloads list to see if the file was downloaded? – NotMe Jun 23 '11 at 17:26
  • no, not in chrome, nor firefox. Infact, the response is empty so it has to be something codebehind. – LocustHorde Jun 23 '11 at 17:26
  • @keyboardP @Chris Lively my page is using update panel, could that be a cause of this? if yes, how do I cancel that, just from this child page? (update panel is in masterpage) – LocustHorde Jun 23 '11 at 17:31
  • Yes, that it most likely the problem. A response stream needs a full postback. Try moving your button outside of the UpdatePanel div or not making it a trigger. Alternatively, check the post with `3 votes` in this thread http://stackoverflow.com/questions/5461525/download-feature-not-working-within-update-panel-in-asp-net – keyboardP Jun 23 '11 at 17:35

4 Answers4

6

reading your comments and edit, looks like you want to cancel ajax postback for just this one button from child page and your update panel is in master page and you can't access it.

If I have that details correct, just add this code on your child content page's PageLoad():

        ScriptManager sm = ScriptManager.GetCurrent(Page);
        if (sm != null)
            sm.RegisterPostBackControl(btnDownload); 
        //btnDownload = the button ID, just copied from your code.

That will force full page postback and your files will be downloaded.

Community
  • 1
  • 1
iamserious
  • 5,385
  • 12
  • 41
  • 60
3

I would prefer doing that on a WebHandler .ashx file. Separated from the main page you are at.

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;

public class Handler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.AddHeader("content-disposition", "attachment; filename=file.csv");
        context.Response.ContentType = "text/csv";
        context.Response.Write("1,2,3,4,5,6");
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
Michael D. Irizarry
  • 6,186
  • 5
  • 30
  • 35
0

From what I can see on your code it seems you are sending that response as part of a post-back. I don't know if you are using WebForms (ASPX) or MVC, but if you are using traditional ASP.NET you can create a new page called "CSV.aspx", remove the entire HTML body of the response and do something like this:

on CSV.aspx:

<%@ Page Title="" Language="C#" AutoEventWireup="true"
    CodeBehind="CSV.aspx.cs" Inherits="TestASPNET.CSV" %>

And on the code-behind (CSV.aspx.cs):

public partial class CSV : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.AddHeader("content-disposition", "attachment; filename=tmp.csv");
        Response.ContentType = "application/octet-stream";
        Response.Write("one,two,three,four,five");
    }
}

Also, notice the ContentType is not text/csv.

Marcelo Calbucci
  • 5,845
  • 3
  • 18
  • 22
  • Hi, I am using webforms, and the reason it has to be on a button submit is because well 1) the csv content is generated dynamically, 2) I have to log some details about the client, 3) this is some terrible legacy system and I dont have permissions to add a new page as an Intern. So I'd have to somehow cancel the ajax postback and get it done. thanks. – LocustHorde Jun 23 '11 at 17:37
  • Wait, if this is an AJAX call it won't ever work. You have to redirect the user otherwise the browser won't prompt to open the file. What I forgot to say is that on your btnDownload_click you have to redirect to CSV.aspx (or send an AJAX response instructing the browser to do so, preferably on a new window). If the CSV is dynamic or static it doesn't matter. – Marcelo Calbucci Jun 23 '11 at 17:48
0

Try calling Response.Flush() in between Response.Write() and Response.End(). Also, don't use an <asp:Button for this. Use an <asp:HyperLinK (or even just a normal <a href anchor) that points to a different page (or, even better, a *.ashx handler) that will give this response.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794