Skalis
Skalis

Reputation: 197

Detect Response.BinaryWrite on client

I have a page with an image button. When the user clicks on the image button, the server creates a PDF of the page and a Response with a download is sent back to the client. The problem is that this can take some time. How can/should I handle the waiting for the client?

My initial thought was to do a onClientClick event on the button that shows a loader GIF. But I am not able to detect when the response is finished so that I can hide it again. I have tried using RegisterStartupScript as well as a Response.Write([script]), but it all seems to get overriden by the PDF's Response.BinaryWrite(buffer) - the file gets downloaded but nothing else happens.

Here's my code with just the download logic:

protected void imgPrint_Click(object sender, ImageClickEventArgs e)
        {
            PDF pdf = new PDF();

            byte[] buffer = pdf.ExportToPDF(Request.QueryString["id"].ToString(), Request.QueryString["mode"].ToString());

            string att = "attachment; filename=" + Request.QueryString["mode"].ToString() + ".pdf";
            Response.ClearContent();
            Response.AddHeader("content-disposition", att);
            Response.ContentType = "application/pdf";
            Response.ContentEncoding = Encoding.Default;
            Response.BinaryWrite(buffer);
        }

And the image button with an onClientClick event that currently only shows an alert:

<asp:ImageButton ID="imgPrint" runat="server" 
                              ImageUrl="~/bilder/skriv_ut.png" Width="45" Height="36" 
                              onclick="imgPrint_Click" OnClientClick="loader(true);" />

Upvotes: 1

Views: 1571

Answers (2)

Mr.LamYahoo
Mr.LamYahoo

Reputation: 1546

in the webform, you can use Jquery & Webservice

function loader(show) {
  if(show)
  {
    //show loading here
  }

       $.ajax({
           type: "POST",
           url: "MyService.asmx/myMethod",
           data: "{}",
           contentType: "application/json; charset=utf-8",
           dataType: "json",
           success: function (data) {
                //do some thing & hide loading
           },
           error: function (data) {
                //do some thing & hide loading
           }
       });
   }
});

[WebService, ScriptService]
public class MyService : WebService
{

    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public static string myMethod()
    {
        PDF pdf = new PDF();

            byte[] buffer = pdf.ExportToPDF(Request.QueryString["id"].ToString(), Request.QueryString["mode"].ToString());

            string att = "attachment; filename=" + Request.QueryString["mode"].ToString() + ".pdf";
            Response.ClearContent();
            Response.AddHeader("content-disposition", att);
            Response.ContentType = "application/pdf";
            Response.ContentEncoding = Encoding.Default;
            Response.BinaryWrite(buffer);
            return "ok";
    }
}

Upvotes: 1

Lev
Lev

Reputation: 3924

Generally, I use Generic Handler and Hyperlink for downloadable files, or pictures.

Generic Handler:

public class DocumentsHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            Document doc; // any type

            if (doc!= null)
            {
                context.Response.ContentType = MimeMapping.GetMimeMapping(doc.FileName);
                context.Response.AddHeader("Content-Disposition", string.Format("filename={0}", doc.FileName));
                context.Response.OutputStream.Write(doc.Data, 0, doc.Data.Length);
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

.cs page:

lnkDocument.NavigateUrl = String.Format("~/Handlers/DocumentsHandler.ashx?{0}",documentId);

When users want to view/download file they click on hyperlink. In your case web page will load immediately, and time consuming process will go after clicking on hyperlink.

Upvotes: 0

Related Questions