使用Handler跟踪文件

Izz*_*zzy 10 c# asp.net

我目前正在开发一个使用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)

我感谢你的帮助和支持.

TcK*_*cKs 4

我尝试创建简单的处理程序,它可以从服务器端的角度检测下载是否被取消/中断。

重要的部分是发送数据期间/之后的“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)