C# - Problems with Scriptmanager after Response

Asked

Viewed 121 times

0

Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Comprovante.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);.
-- código de envio de e-mail e baixa de pdf
Response.Write(pdfDocParc);

Basically I have it on a save button, and after that I try to generate a saved changes Alert:

Page.ClientScript.RegisterStartupScript(typeof(Page), "Test", "<script type='text/javascript'>alert('Alerações salvas com sucesso!');</script>");
Buscar(); -- método que atualiza a página com as alterações salvas

However I’m not getting, it goes through the line and generates nothing, just download the pdf. I saw something like this in this question: Problems with Scriptmanager.Registerclientscriptblock

But I couldn’t figure out how to fix it.

Someone would have a solution?

  • In the WebForms a download needs to be run through a PostBack. Simply put, it means that your response will only return the document and nothing more.

  • Yes, he is returning the right document, I also perform an email sending together. But after the download part, I can not update the page with the method, goes through it but does nothing.. Even Alert is not triggered, it only actually downloads.

  • That is why I commented that will return only your document and nothing else. It is no use to register anything on ScriptManager that this will not return in response... If you want to do this, you’ll have to change your approach.

  • A long time ago I wrote this in a Webforms project, opening the document in a pop up (very long time)... maybe opening in a new tab you get the same outline

1 answer

0


When you send a downloadable document to the user, you cannot mix the information in your response. This means that you cannot have part of the answer being a document and another HTML part.

That’s why the part where you programmed to "refresh" the page doesn’t work. This refresh page, at the end of the accounts is HTML and your HTTP response is a document.

It is possible yes, download and refresh the page, but you would have to change your logic. Updating the page first and downloading later... This can be done in several ways...

Solution 1:

This solution would basically use the latest functions of the browsers, which allow you to have a anchor with a document in base64 and by "clicking" on this chor would be downloaded.

Taking advantage of this function, we could do the following: We updated this anchor on the server and then simulate a click on it.

.aspx

<asp:UpdatePanel ID="uppDownload" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Button ID="btnDownload" runat="server" Text="Download" OnClick="btnDownload_Click" />
        <a id="download" runat="server" href="" download="" />
    </ContentTemplate>
</asp:UpdatePanel>

Codebehind

protected void btnDownload_Click(object sender, EventArgs e)
{
    string arquivo = @"C:\temp\testes.pdf";

    download.Attributes["href"] = $"data:application/pdf;base64, {Convert.ToBase64String(File.ReadAllBytes(arquivo))}";
    download.Attributes["download"] = "teste.pdf";

    //Aqui o script simularia o clique naquela anchor que mencionou antes
    string script = "setTimeout(function(){ alert('Funcionou!');  $get('" + download.ClientID + "').click(); },2000);";

    ScriptManager.RegisterStartupScript(Page, typeof(Page), "download_script", script, true);
}

Solution 2:

Refresh page and then make a request to own page indicating where is the document to download through parameters:

.aspx

<asp:UpdatePanel ID="uppDownload" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Button ID="btnDownload" runat="server" Text="Download" OnClick="btnDownload_Click" />
    </ContentTemplate>
</asp:UpdatePanel>

Codebehind

protected void btnDownload_Click(object sender, EventArgs e)
{
    //Aqui o script simularia o clique naquela anchor que mencionou antes
    string script = "setTimeout(function(){ alert('Funcionou!');  window.location.href = window.location.pathname + '?' + 'download=1'; }, 2000);";
    ScriptManager.RegisterStartupScript(Page, typeof(Page), "download_script", script, true);
}

protected void Page_Load(object sender, EventArgs e)
{
    if (Request.Params?["download"] == "1")
    {
        string filePath = @"C:\temp\testes.pdf";
        FileInfo myfile = new FileInfo(filePath);

        if (myfile.Exists)
        {
            Response.ClearContent();
            Response.AddHeader("Content-Disposition", "attachment; filename=" + myfile.Name);
            Response.AddHeader("Content-Length", myfile.Length.ToString());
            Response.ContentType = "application/octet-stream";
            Response.TransmitFile(filePath);
            Response.Flush();
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
    }
}

Solution 3:

Simulate solution 2, only instead of doing it on the page itself, do it with a IFrame:

.aspx

<asp:UpdatePanel ID="uppDownload" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Button ID="btnDownload" runat="server" Text="Download" OnClick="btnDownload_Click" />
        <iframe id="downloadFrame" runat="server" />
    </ContentTemplate>
</asp:UpdatePanel>

Codebehind

protected void btnDownload_Click(object sender, EventArgs e)
{
    //Aqui o script simularia o clique naquela anchor que mencionou antes
    string script = "setTimeout(function(){ alert('Funcionou!');  $get('" + downloadFrame.ClientID + "').src = window.location.pathname + '?' + 'download=1'; }, 2000);";
    ScriptManager.RegisterStartupScript(Page, typeof(Page), "download_script", script, true);
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.