views:

827

answers:

7

Hi, I would like to create a text file for export/download, like a *.csv, from an ASP.NET application. I know about Response.TransmitFile, but I want to do this without creating and saving a file physically on the server. Is that possible? Has anyone done something like that?

+1  A: 

A file you haven't saved yet is just a string variable or a MemoryStream. But for large amounts of data you probably don't want to keep it all in memory. What do you want to do with this "file" once you have it?

Joel Coehoorn
I would like to download it
+9  A: 

When you say "Create a file for export", I am understanding that you want to make it downloadable to the browser. If that's the case, here's an example.

public void btnGo_Click (Object sender, EventArgs e)
{
    Response.Clear();

    string fileName= String.Format("data-{0}.csv", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss")); 
    Response.ContentType = "text/csv";
    Response.AddHeader("content-disposition", "filename=" + fileName);

    // write string data to Response.OutputStream here
    Response.Write("aaa,bbb,ccc\n");

    Response.End();
}

cite: RFC 4180

Cheeso
I assume you intend that this be placed in a normal ASPX page? That would work, of course, but isn't really optimal. There will be some overhead for initialising/beginning to generate the ASPX page in the start.
Noldorin
yes, this would go in a "normal" ASPX page. Not sure what you mean by overhead, or why what I have here is sub-optimal.
Cheeso
Yeah, an ASHX should do the job fine. I suggested a custom HTTP handler, but either would work well here.
Noldorin
@Cheeso: Your clearing the response stram before outputing the "real" data. ASP.NET does a lot behind the scenes to load the page before it even reaches calling your event handler.
Noldorin
I see! Thank you for that clarification.
Cheeso
No problem. If you simply remove the `Response.Clear` and place that code in an ASHX instead, there would be no issues whatsoever.
Noldorin
One possible correction - you may need to set the content-disposition header to "attachment; filename=" + filename.
Jason Musgrove
+1  A: 

You could write direcly to the Response.OutputStream and set the right content type, and content disposition header.

CMS
A: 

Oh, that is not bad. In your ASPX page's Page_Load do this:

Response.ContentType = "text/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.Write(/* your text goes here */);

The above is an example if your 'file' is xml, but it can be anything, from and excel file to a pdf. All you have to do is update the ContentType which you can lookup via Google or Live.

JasonRShaver
wow you people are fast... =)
JasonRShaver
A: 

Try this sample:

protected void Button1_Click(object sender, EventArgs e)
{
     Response.ContentType = "text/csv";
     Response.AddHeader("content-disposition", "attachment; filename=download.csv");
     Response.Write("your,csv,file,contents");
     Response.End();
}
NinethSense
+4  A: 

You'll want to look at writing a Custom HTTP Handler (a class that implements IHttpHandler) and simply register it in web.config. See this article on MSDN for a good example of how to set one up.

Here's a basic example of how you might go about implementing one to return the markup for some CSV data.

using System.Web;

public class MyCsvDocumentHandler : IHttpHandler
{
    public static string Data
    {
        get;
        set;
    }

    public MyCsvDocumentHandler()
    {
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/csv"; // Set the MIME type.
        context.Response.Write(Data); // Write the CSV data to the respone stream.
    }

    public bool IsReusable
    {
        // To enable pooling, return true here.
        // This keeps the handler in memory.
        get { return false; }
    }
}

This alternative, which is possibly slightly simpler, is to use an ASHX handler page. The code would be almost identical.

Noldorin
Note that it's also possible (if under-documented) to link an an IHTTPHandler without munging your web.config - the ASHX 'page' type provides wiring for you.
Tetsujin no Oni
(I have used this technique for generating graphical buttons dynamically in the past, I think it's pretty useful).
Tetsujin no Oni
@Tetsujin: Yeah, absolutely. In some cases a HTTP handler (IHttpHandler) is more desirable, since it offers slightly more flexibility, but an ASHX would be just as good in this case.
Noldorin
A: 

Thanks guys, this worked for me. I used a combination of the above comments to get mine working.