asp.net on button click create CSV file, download it and refresh page

10,267

You are going to need to use some javascript on the client to get the results you want. I have taken the basics from here https://stackoverflow.com/a/4168965/1002621 which is an example with a php back-end.

The code you need on the client will look something like this the basic premise is that you use jquery to intercept your download buttons click event so a token can be injected into the form post which you can then send back in the response to know the file download is done and then do your own form submit / whatever.

<script type="text/javascript">

    function DownloadAndRefresh() {

        //get form and inject a hidden token input
        var form = $(this).closest('form');
        var tokenInput = $('input[name=token]');
        if (tokenInput.length == 0) {
            tokenInput = $('<input />').prop('type', 'hidden').prop('name', 'token');
            form.append(tokenInput);
        }

        //create a unqiue token we can watch for and set the hidden inputs value
        var token = new Date().getTime();
        tokenInput.prop('value', token);

        //watch for the token to come back in the documents cookie (this is set on server)
        var tokenInterval = setInterval(function () {
            //check to see if the cookie contains the token yet
            if (document.cookie.indexOf(token) != -1) {
                //submit the form again now the file has been downloaded (this causes a standard postback)
                form[0].submit();
                window.clearInterval(tokenInterval);
            }
        }, 200);

        //wait up to 60 seconds for the token then stop the interval because something probably went wrong
        setTimeout(function () { window.clearInterval(tokenInterval); }, 60000);

        //allow the current post action to continue
        return true;

    }

    $(document).ready(function () {
        //call the DownloadAndRefresh function before posting to the server
        $('#<%= DownloadButton.ClientID %>').on('click', DownloadAndRefresh);
    });

</script>

<asp:Button runat="server" ID="DownloadButton" Text="Download Button" onclick="Download_Click" /> 

The server code is pretty simple and just needs to pull the token out of the request form and put it in the response cookie.

    protected void Download_Click(object sender, EventArgs e)
    {
        Response.Clear();

        //set the response token cookie to be the token sent in the form request
        Response.SetCookie(new HttpCookie("token", Request.Form["token"]));
        Response.Buffer = true;
        Response.AddHeader("content-disposition", "attachment;filename=file.txt");
        Response.ContentType = "text/plain";
        Response.Output.Write("some text");
        Response.End();
    }
Share:
10,267
renathy
Author by

renathy

Updated on June 04, 2022

Comments

  • renathy
    renathy almost 2 years

    Is it impossible to gather information from page (and databaes), create csv file from given information, download created file and refresh page?

    Currently user sees a table with rows, select rows by checking checkboxes, press Export button and CSV file is created and downloaded to users computer. The problem is with Page Refresh.

    Currently on button click CSV is created and downloaded in the following way:

            //here is create csv function and then the result is outputed
            Response.Clear()
            Response.Buffer = True
            Response.AddHeader("content-disposition", "attachment;filename=DataTable.csv")        
            Response.Charset = ""
            Response.ContentType = "application/text"
    
            Response.Output.Write(CsvFile.ToString(), 0)
            Response.Flush()
            Response.End()
    

    This soultion makes problems with Page refresh after csv file is downloaded.

    1) This link: Redirecting to another page after Response.End() has been called in C#

    suggests `Response.AddHeader("Refresh", "3; url=index.html"); that should refresh page. This doesn't work, no redirect happens.

    2) Another sollution suggested is creating some additional URL and allow user to download file from given URL. This doesn't fit my situation, because File is created from data on the page.

    3) Is there any other solution that fits needs (button click creates csv and downloads it, page is refreshed)?

    Can you give me some clues, please?

    • LiverpoolsNumber9
      LiverpoolsNumber9 over 10 years
      You can't do this. The 'End' in Response.End() is your biggest clue.
    • renathy
      renathy over 10 years
      You say that it is impossible to gather information from page, create csv file, download it and refresh page?
    • user2674389
      user2674389 over 10 years
      It's really unclear what exactly you want. Do you want to provide a file for download? Then do this, but you can't redirect the user to another Uri once he finished downloading.
    • LiverpoolsNumber9
      LiverpoolsNumber9 over 10 years
      There is only one "response" per request. If the type of your response is "file", what do you expect?
    • renathy
      renathy over 10 years
      I want user to click button, that will create new file from data on the page (export table rows into CSV) and download this file to user computer. After download I need refresh page (this will remove exported rows from table).
    • user2674389
      user2674389 over 10 years
      You can't download and refresh the page in the same time. Your best choice is simply to open the download in a new window (using JavaScript).
    • Tim
      Tim over 10 years
      You can try a response.Redirect back to the page you're on instead of a Response.End, but it may not behave the way you want it to...
    • renathy
      renathy over 10 years
      How to use javascript for this purpose? I mean, I have to take information from page and from database, create csv file and download it?
    • renathy
      renathy over 10 years
      And if Response.Redirect is used instead Response.End it gives "Cannot redirect after HTTP headers have been sent."
    • the_lotus
      the_lotus over 10 years