在ASP.NET中如何检测文件下载完成?

时间:2022-03-30 15:17:35

I have a popup window that displays "Please wait while your file is being downloaded". This popup also executes the code below to start the file download. How can I close the popup window once the file download has completed? I need some way to detect that the file download has completed so I can call self.close() to close this popup.

我有一个弹出窗口,显示“请在下载文件时等待”。这个弹出窗口还执行下面的代码来启动文件下载。文件下载完成后,如何关闭弹出窗口?我需要一些方法来检测文件下载是否已经完成,以便我可以调用self.close()来关闭这个弹出窗口。

System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ClearHeaders();
System.Web.HttpContext.Current.Response.ContentType = fileObject.ContentType;
System.Web.HttpContext.Current.Response.AppendHeader("Content-Disposition", string.Concat("attachment; filename=", fileObject.FileName));
System.Web.HttpContext.Current.Response.WriteFile(fileObject.FilePath);
Response.Flush();
Response.End();

5 个解决方案

#1


3  

An idea:

一个想法:

If you handle the file downloading yourself in server side code by writing chunk by chunk to the response stream, then you'll know when the file had finished downloading. You would simply have to connect the FileStream to the response stream, send data chunk by chunk, and redirecting after complete. This can be inside your popup window.

如果您在服务器端代码中通过将块按块写入响应流来处理该文件,那么您将知道该文件何时完成了下载。您只需将FileStream连接到响应流,按块发送数据块,并在完成后重定向。这可以在你的弹出窗口里面。

Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-disposition", "attachment; filename=bob.mp3");
Response.AppendHeader("content-length", "123456789");

Make sure you check Response.IsClientConnected when writing out to the response stream.

确保检查响应。当写入响应流时,isclient连接。

#2


1  

There is a solution where you can track the download status by transferring the file as smaller packets and check whether all the packets have been transferred. The solution is not mine but you can find it here: File Download in ASP.NET and Tracking the Status of Success/Failure of Download

有一种解决方案,您可以通过将文件作为小数据包传输来跟踪下载状态,并检查所有包是否已被传输。解决方案不是我的,但你可以在这里找到:文件下载在ASP。NET和跟踪下载成功/失败的状态

//Function for File Download in ASP.Net in C# and 
//Tracking the status of success/failure of Download.
private bool DownloadableProduct_Tracking()
{
//File Path and File Name
string filePath = Server.MapPath("~/ApplicationData/DownloadableProducts");
string _DownloadableProductFileName = "DownloadableProduct_FileName.pdf";

System.IO.FileInfo FileName = new System.IO.FileInfo(filePath + "\\" + _DownloadableProductFileName);
FileStream myFile = new FileStream(filePath + "\\" + _DownloadableProductFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

//Reads file as binary values
BinaryReader _BinaryReader = new BinaryReader(myFile);

//Ckeck whether user is eligible to download the file
if (IsEligibleUser())
{
//Check whether file exists in specified location
if (FileName.Exists)
{
    try
    {
    long startBytes = 0;
    string lastUpdateTiemStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
    string _EncodedData = HttpUtility.UrlEncode(_DownloadableProductFileName, Encoding.UTF8) + lastUpdateTiemStamp;

    Response.Clear();
    Response.Buffer = false;
    Response.AddHeader("Accept-Ranges", "bytes");
    Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
    Response.AppendHeader("Last-Modified", lastUpdateTiemStamp);
    Response.ContentType = "application/octet-stream";
    Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName.Name);
    Response.AddHeader("Content-Length", (FileName.Length - startBytes).ToString());
    Response.AddHeader("Connection", "Keep-Alive");
    Response.ContentEncoding = Encoding.UTF8;

    //Send data
    _BinaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);

    //Dividing the data in 1024 bytes package
    int maxCount = (int)Math.Ceiling((FileName.Length - startBytes + 0.0) / 1024);

    //Download in block of 1024 bytes
    int i;
    for (i = 0; i < maxCount && Response.IsClientConnected; i++)
    {
        Response.BinaryWrite(_BinaryReader.ReadBytes(1024));
        Response.Flush();
    }
    //if blocks transfered not equals total number of blocks
    if (i < maxCount)
        return false;
    return true;
    }
    catch
    {
    return false;
    }
    finally
    {
    Response.End();
    _BinaryReader.Close();
    myFile.Close();
    }
}
else System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(),
    "FileNotFoundWarning","alert('File is not available now!')", true);
}
else
{
System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(), 
    "NotEligibleWarning", "alert('Sorry! File is not available for you')", true);
}
return false;
}

#3


0  

Some hacks are around that involves knowing when the last piece of the buffer has been sent or checking the HttpResponse.IsClientConnected property.

一些技巧涉及到知道何时发送了缓冲区的最后一部分,或者检查HttpResponse。IsClientConnected财产。

#4


0  

I handle the problem differently in Javascript, which might or might not work for you.

我在Javascript中处理问题的方式不同,这可能对您有用,也可能不适合您。

  • Create a hidden DIV element, with the message 'File is downloading...' rather than a pop-up box.
  • 创建一个隐藏的DIV元素,消息的文件正在下载…而不是弹出框。
  • Show the div when the download starts
  • 下载开始时显示div
  • Once any other element on the forms is clicked, hide the div again..
  • 单击表单上的任何其他元素后,再次隐藏div。
  • You could also set a timer to hide the download message div after so amount of time...
  • 您还可以设置一个定时器来隐藏下载消息div,在这么多时间之后…

I figure once the user clicks on another element, she either already knows the download is done, or she is ready to do something else, so the message becomes irrelevant and can go away....

我想一旦用户点击另一个元素,要么她已经知道下载完成,或者她是准备做点别的,所以消息变得无关紧要,可以消失....

#5


0  

The way to do that is in your pop-up to call the server via AJAX polling for some response which would indicate the file was flushed.

这样做的方法是在弹出窗口中,通过AJAX轮询调用服务器以获得一些响应,这些响应将表明文件已被刷新。

Ex: right before sending the file, store sessionID+FileName in a DB or session or what have you.

在发送文件之前,将sessionID+文件名存储在一个DB或会话中,或者其他什么。

On the client, in your popup, poll a web-service via AJAX - this could even be a WebMethod like Bool IsContentFlushed(string sessionID, string fileName);

在客户端,在弹出窗口中,通过AJAX轮询web服务——这甚至可以是一个WebMethod,比如Bool iscontentflush (string sessionID, string fileName);

After you do Response.Flush(); remove this sessionID+FileName from your store.

后你Response.Flush();从存储中删除这个sessionID+文件名。

Call Response.Close() instead of Response.End() - the later is very brutal, and is usually over-kill.

Call Response.Close()而不是Response.End()——后者是非常残酷的,通常是过度的。

#1


3  

An idea:

一个想法:

If you handle the file downloading yourself in server side code by writing chunk by chunk to the response stream, then you'll know when the file had finished downloading. You would simply have to connect the FileStream to the response stream, send data chunk by chunk, and redirecting after complete. This can be inside your popup window.

如果您在服务器端代码中通过将块按块写入响应流来处理该文件,那么您将知道该文件何时完成了下载。您只需将FileStream连接到响应流,按块发送数据块,并在完成后重定向。这可以在你的弹出窗口里面。

Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-disposition", "attachment; filename=bob.mp3");
Response.AppendHeader("content-length", "123456789");

Make sure you check Response.IsClientConnected when writing out to the response stream.

确保检查响应。当写入响应流时,isclient连接。

#2


1  

There is a solution where you can track the download status by transferring the file as smaller packets and check whether all the packets have been transferred. The solution is not mine but you can find it here: File Download in ASP.NET and Tracking the Status of Success/Failure of Download

有一种解决方案,您可以通过将文件作为小数据包传输来跟踪下载状态,并检查所有包是否已被传输。解决方案不是我的,但你可以在这里找到:文件下载在ASP。NET和跟踪下载成功/失败的状态

//Function for File Download in ASP.Net in C# and 
//Tracking the status of success/failure of Download.
private bool DownloadableProduct_Tracking()
{
//File Path and File Name
string filePath = Server.MapPath("~/ApplicationData/DownloadableProducts");
string _DownloadableProductFileName = "DownloadableProduct_FileName.pdf";

System.IO.FileInfo FileName = new System.IO.FileInfo(filePath + "\\" + _DownloadableProductFileName);
FileStream myFile = new FileStream(filePath + "\\" + _DownloadableProductFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

//Reads file as binary values
BinaryReader _BinaryReader = new BinaryReader(myFile);

//Ckeck whether user is eligible to download the file
if (IsEligibleUser())
{
//Check whether file exists in specified location
if (FileName.Exists)
{
    try
    {
    long startBytes = 0;
    string lastUpdateTiemStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
    string _EncodedData = HttpUtility.UrlEncode(_DownloadableProductFileName, Encoding.UTF8) + lastUpdateTiemStamp;

    Response.Clear();
    Response.Buffer = false;
    Response.AddHeader("Accept-Ranges", "bytes");
    Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
    Response.AppendHeader("Last-Modified", lastUpdateTiemStamp);
    Response.ContentType = "application/octet-stream";
    Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName.Name);
    Response.AddHeader("Content-Length", (FileName.Length - startBytes).ToString());
    Response.AddHeader("Connection", "Keep-Alive");
    Response.ContentEncoding = Encoding.UTF8;

    //Send data
    _BinaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);

    //Dividing the data in 1024 bytes package
    int maxCount = (int)Math.Ceiling((FileName.Length - startBytes + 0.0) / 1024);

    //Download in block of 1024 bytes
    int i;
    for (i = 0; i < maxCount && Response.IsClientConnected; i++)
    {
        Response.BinaryWrite(_BinaryReader.ReadBytes(1024));
        Response.Flush();
    }
    //if blocks transfered not equals total number of blocks
    if (i < maxCount)
        return false;
    return true;
    }
    catch
    {
    return false;
    }
    finally
    {
    Response.End();
    _BinaryReader.Close();
    myFile.Close();
    }
}
else System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(),
    "FileNotFoundWarning","alert('File is not available now!')", true);
}
else
{
System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(), 
    "NotEligibleWarning", "alert('Sorry! File is not available for you')", true);
}
return false;
}

#3


0  

Some hacks are around that involves knowing when the last piece of the buffer has been sent or checking the HttpResponse.IsClientConnected property.

一些技巧涉及到知道何时发送了缓冲区的最后一部分,或者检查HttpResponse。IsClientConnected财产。

#4


0  

I handle the problem differently in Javascript, which might or might not work for you.

我在Javascript中处理问题的方式不同,这可能对您有用,也可能不适合您。

  • Create a hidden DIV element, with the message 'File is downloading...' rather than a pop-up box.
  • 创建一个隐藏的DIV元素,消息的文件正在下载…而不是弹出框。
  • Show the div when the download starts
  • 下载开始时显示div
  • Once any other element on the forms is clicked, hide the div again..
  • 单击表单上的任何其他元素后,再次隐藏div。
  • You could also set a timer to hide the download message div after so amount of time...
  • 您还可以设置一个定时器来隐藏下载消息div,在这么多时间之后…

I figure once the user clicks on another element, she either already knows the download is done, or she is ready to do something else, so the message becomes irrelevant and can go away....

我想一旦用户点击另一个元素,要么她已经知道下载完成,或者她是准备做点别的,所以消息变得无关紧要,可以消失....

#5


0  

The way to do that is in your pop-up to call the server via AJAX polling for some response which would indicate the file was flushed.

这样做的方法是在弹出窗口中,通过AJAX轮询调用服务器以获得一些响应,这些响应将表明文件已被刷新。

Ex: right before sending the file, store sessionID+FileName in a DB or session or what have you.

在发送文件之前,将sessionID+文件名存储在一个DB或会话中,或者其他什么。

On the client, in your popup, poll a web-service via AJAX - this could even be a WebMethod like Bool IsContentFlushed(string sessionID, string fileName);

在客户端,在弹出窗口中,通过AJAX轮询web服务——这甚至可以是一个WebMethod,比如Bool iscontentflush (string sessionID, string fileName);

After you do Response.Flush(); remove this sessionID+FileName from your store.

后你Response.Flush();从存储中删除这个sessionID+文件名。

Call Response.Close() instead of Response.End() - the later is very brutal, and is usually over-kill.

Call Response.Close()而不是Response.End()——后者是非常残酷的,通常是过度的。