我目前正在开发一个使用Asp.Net和C#开发的网站.我正在利用Asp.Net Handler允许用户下载文件.我可以下载文件没问题.但是我需要记录哪些文件已成功下载.这部分似乎对我不起作用.例如,如果我单击要下载的文件,然后在浏览器提示上单击取消,我的代码仍会写入日志.我似乎无法弄清楚只有在文件成功下载后才能写入日志.
我的代码如下.
public void ProcessRequest(HttpContext context)
{
string logFilePath = "PathToMyLogFile";
string filePath = Uri.UnescapeDataString(context.Request.QueryString["file"]);
string fileName = Path.GetFileName(filePath);
if (context.Response.IsClientConnected) //Shouldn't this tell me if the client is connected or not?
{
using (var writer = new StreamWriter(logFilePath, true))
{
if (!File.Exists(logFilePath))
{
//Create log file if one does not exist
File.Create(logFilePath);
}
else
{
writer.WriteLine("The following file was downloaded \"{0}\" on {1}", fileName, DateTime.Now.ToString("dd/MM/yyyy") + " at " + DateTime.Now.ToString("HH:mm:ss"));
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
}
}
}
context.Response.ContentType = "application/octet-stream";
context.Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + Path.GetFileName(filePath));
context.Response.WriteFile(filePath);
context.Response.End();
}
Run Code Online (Sandbox Code Playgroud)
我感谢你的帮助和支持.
我尝试创建简单的处理程序,它可以从服务器端的角度检测下载是否被取消/中断。
重要的部分是发送数据期间/之后的“context.Response.IsClientConnected”。
此示例将发送带有随机数据的永无休止的文件。您可以在所有浏览器中测试它们的行为方式。我只在 Chrome 中测试过。
/// <summary>
/// Writes random data.
/// </summary>
public class NeverendingFile : IHttpHandler {
public bool IsReusable {
get { return false; }
}
public void ProcessRequest(HttpContext context) {
context.Response.Buffer = false;
context.Response.BufferOutput = false;
context.Response.ContentType = "application/octet-stream";
context.Response.AppendHeader("Content-Disposition", "attachment;filename=\"Neverendingfile.dat\"");
context.Response.Flush();
// flag used for debuging, in production it will be always false => writing into output stream will nevere ends
var shouldStop = false;
for(var i = 0; !shouldStop; i++) {
// chunk contains random data
var chunk = Guid.NewGuid().ToByteArray();
for (var a = 0; a < 1000; a++) {
context.Response.OutputStream.Write(chunk, 0, chunk.Length);
}
context.Response.OutputStream.Flush();
// sleep is just for slowing the download
System.Threading.Thread.Sleep(10);
if (!context.Response.IsClientConnected) {
// the download was canceled or broken
return;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑: 编辑源代码:
public void ProcessRequest(HttpContext context) {
string logFilePath = "PathToLogFile";
//Determine the file path
string filePath = Uri.UnescapeDataString(context.Request.QueryString["file"]);
//Determine the file name
string fileName = Path.GetFileName(filePath);
context.Response.Buffer = false;
context.Response.BufferOutput = false;
context.Response.ContentType = "application/octet-stream";
context.Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + Path.GetFileName(filePath));
context.Response.WriteFile(filePath);
context.Response.Flush();
context.Response.OutputStream.Flush();
if (!context.Response.IsClientConnected) {
// the download was canceled or broken
using (var writer = new StreamWriter(logFilePath, true)) {
if (!File.Exists(logFilePath)) {
//Create log file if one does not exist
File.Create(logFilePath);
}
else {
writer.WriteLine("The Download was canceled");
}
}
return;
}
context.Response.End();
}
Run Code Online (Sandbox Code Playgroud)