我目前正在开发一个使用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();
}
感谢您的所有帮助和支持。
答案 0 :(得分: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;
}
}
}
}
修改强> 编辑过的源代码:
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();
}
答案 1 :(得分:1)
我假设下载和取消按钮都在同一页面上。 我创建了以下示例来检查文件是否已经开始下载,同时取消使用具有标记的单例类&#34; isFileDownload&#34;这样就不会为同一用户的每个请求初始化标志值。
仅供参考,我是处理人员的新手。如果我在发布此内容时遗漏了一些内容,请提前预订
处理程序类:
public class DownloadFile : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string fileName = @"test.txt";
string filePath = context.Server.MapPath("/test.txt");
string logFilePath = context.Server.MapPath("/Log.txt");
//string filePath = Uri.UnescapeDataString(context.Request.QueryString["file"]);
//string fileName = Path.GetFileName(filePath);
Singleton s = Singleton.Instance;
s.isFileDownload = Convert.ToBoolean(context.Request.Form["isFileDownload"]);
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);
}
}
}
//To mock the large file download
if (s.isFileDownload)
System.Threading.Thread.Sleep(10000);
if (context.Response.IsClientConnected )
{
if (s.isFileDownload){
System.Threading.Thread.Sleep(100);
context.Response.ContentType = "application/octet-stream";
context.Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + Path.GetFileName(filePath));
context.Response.WriteFile(filePath);
context.Response.OutputStream.Flush();
context.Response.End();
}
else
{
return;
}
}
else
{
return;
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
单身人士课程: Reference
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
public bool isFileDownload { get; set; }
}
Html页面:
$(document).ready(function(){
var isFileDownload = false;
$("#download").click(function () {
isFileDownload = true;
console.log(isFileDownload);
$.ajax({
method: "POST",
url: "DownloadFile.ashx",
data: { isFileDownload:true }
}).done(function (data) {
alert(data);
});
});
$("#cancel").click(function () {
if (isFileDownload) {
$.ajax({
method: "POST",
url: "DownloadFile.ashx",
data: { isFileDownload: false }
}).done(function (data) {
alert("canceld");
isFileDownload = false;
});
}
});
$(document).ajaxComplete(function () {
isFileDownload = false;
});
)};
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<button type="button" value="DownLoad" id="download" title="Download">Download</button>
<button type="button" value="Cancel" id="cancel" title="Cancel">Cancel</button>
</body>
&#13;
答案 2 :(得分:0)
当出现浏览器弹出窗口时,表示服务器已开始将数据发送(流)到客户端。实际上无法检测文件下载是否成功。 您只能检测发送到客户端的字节数,如果字节数等于文件长度,您可以假设客户端能够下载文件,但您无法获得证明该文件已成功保存在客户端的计算机/环境中。
示例:如果我在linux下载并将流转发到/ dev / null,您将看到我已经下载了该文件,但实际上该文件将不存在于我的机器上。