Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Response.WriteFile & Response.Redirect

I'm publishing a page URL eg mysite.com/disclaimer/someinfo this page shows an agreement, and if the user clicks the agree button then a PDF file is streamed as an attachment.

The purpose of this is the user can then share this URL but anyone else following the link must also read the agreement before downloading the file. The actual file does not have a URL but is held elsewhere on the server so the only way to download the file is if you click the "[Agree]" button.

However - what I am finding difficult is that after clicking the button and starting the download I'd like the page to "go away". The page with the buttons stays on the screen. Ideally they'd be redirected back to the page they came from. I'm keen to not require javascript or cookies. The referrer is stored in the initial page load to a hidden field on the form.

I've tried different approaches, attempting to write a 307 redirect in the header with the file brought up warnings to the user that their post data was being redirected. The code I have below only works in browsers that support meta refresh (eg Firefox; IE7 not Chrome/Safari)

I can see the logic of why this doesn't work. There's one response to the browser and that is the file as expected. What would be the correct way to send them the file and then redirect the browser to another page. It feels from a users p.o.v. that this "Accept" page should disappear once they've clicked the button.

I have:

protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.UrlReferrer != null & Request.UrlReferrer.ToString() != "")
        {
            Uri referrer = Request.UrlReferrer;
            if (!IsPostBack)
            { hfReferrer.Value = Request.UrlReferrer.ToString(); }
        }
    }

    protected void buttonAccept_Click(object sender, EventArgs e)
    {
        //stream file
        Node nodeCurrent = Node.GetCurrent();
        string fileName = nodeCurrent.GetProperty("documentFile").Value.ToString();
        System.IO.FileInfo file = new System.IO.FileInfo(fileName); 
        if (file.Exists) //set appropriate headers  
        {
            Response.Clear();

            if (hfReferrer.Value !="")
            {Response.AddHeader("Refresh", string.Format("3; URL={0}", hfReferrer.Value));}

            Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
            Response.AddHeader("Content-Length", file.Length.ToString());
            Response.ContentType = "application/pdf";

            // write file to browser
            Response.WriteFile(file.FullName);
            Response.End();
        }

I'd prefer not to need to use javascript/pop-ups etc. Presently the user just has to click a link to go to another page, but this doesn't feel quite right.

Ideally I'd like to follow a good standard for this. But I am not sure where to look.

like image 901
John C Scott Avatar asked Nov 04 '22 06:11

John C Scott


1 Answers

I would suggest to try a slightly different behavior. On the buttonAccept_Click event handler, redirect the user to a thank you page. In the Page_Load of this thank you page have the code for downloading the file. This is very easy to implement, and gives a better experience for the user.

like image 150
Ben Avatar answered Nov 09 '22 15:11

Ben