Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在MVC中检测应用程序的现有下载_C#_Asp.net Mvc_Download - Fatal编程技术网

C# 在MVC中检测应用程序的现有下载

C# 在MVC中检测应用程序的现有下载,c#,asp.net-mvc,download,C#,Asp.net Mvc,Download,我有一个MVC应用程序,它有一个服务于文件的操作。我有一个要求,如果用户已经开始下载,在当前下载完成之前,用户不能开始新的下载 简单地说,用户一次只能下载一个文件。但是,我不想简单地阻止用户的请求,而是想让他们知道他们无法下载新的请求,因为他们正在下载现有的请求 所以我的问题是,当下载已经开始,但还没有完成时,您如何跟踪?我最初转向IIS中的动态ip限制,但问题是最终用户可能坐在层层代理的后面,这可能使其不可靠。有没有办法通过代码来实现这一点 我还尝试使用FileWebRequest/FileW

我有一个MVC应用程序,它有一个服务于文件的操作。我有一个要求,如果用户已经开始下载,在当前下载完成之前,用户不能开始新的下载

简单地说,用户一次只能下载一个文件。但是,我不想简单地阻止用户的请求,而是想让他们知道他们无法下载新的请求,因为他们正在下载现有的请求

所以我的问题是,当下载已经开始,但还没有完成时,您如何跟踪?我最初转向IIS中的动态ip限制,但问题是最终用户可能坐在层层代理的后面,这可能使其不可靠。有没有办法通过代码来实现这一点

我还尝试使用FileWebRequest/FileWebResponse创建一个正在进行的流。但是当一个新的请求进入时,它作为一个新的动作进入,我不知道如何检查前一个流是否仍在进行中

public async Task<ActionResult> Download()
    {
        Session["IsDownloading"]  = true;            
        await ServeFiles();
        return View("Index");
    }

public ActionResult CheckStatus()
    {
        var message = Session["IsDownloading"] ?? "Null";
        return Content(message.ToString());
    }
private async Task ServeFiles()
{
   try
   {    //Download async
   }
   finaly
   {
      Session["IsDownloading"] = false;
   }
}
公共异步任务

***********************更新2016-04-04**********


经过一点搜索,我发现会话(我使用的是SQLServer)在请求结束时保存,因此即使用户管理两个并发请求,会话变量也不会在请求结束前更新,从而使会话中的信息不可靠。现在,我正在寻找一种方法,在更新值后立即手动强制保存会话状态。

我认为您需要3件事:识别用户,检查+阻止他是否有现有下载

最简单的方法是将Session[“isDownloading”]=true;然后检查这个。当他完成下载时,将其设置为false

当客户端想要启动下载时,可以使用javascript调用CheckIsDownloading操作,如果ok,则调用Serve获取文件

在服务中再次检查并阻止他是否正在下载,以避免他攻击js并发出下载请求的情况


注意:如果用户未登录,并且您希望确保只有一次下载,那么用户身份部分很难完成。他可以随时删除cookies(->新会话)并进行新的下载。

我最终使用的最终解决方案类似于@eugen的答案,但不是会话,而是使用数据缓存(MemoryCache),它会立即生效,不会等待请求完成。尽管这只是一个过程,但这很好,因为我发现,即使应用程序服务器将实现负载平衡,一旦建立了会话,客户端基础设施也可以保证它们将在会话的其余部分使用同一组服务器


我同意Erik Funkenbusch的意见,即用户可以轻松绕过此问题,此解决方案仅适用于此特定要求。

我尝试过此方法,但似乎无法使其正常工作。因此,我在服务操作开始时添加了一个Session[“IsDownloading”]=true,并在下载后将其更新为false。然后我创建了另一个action CheckStatus,它只读取会话,但是,它似乎被阻止了,并且在下载完成之前不会响应。不确定你所说的阻止是什么意思,你调试了它,并且它停留在你从会话读取的行上?那会很奇怪。也许您可以使用客户端和服务器实现更新您的问题,而不需要包含实际的文件读取代码更新的问题和代码。如果您尝试下载(Download1/2)并单击“检查状态”,则在下载完成之前不会响应。@Eugen-即使询问者能够想出如何进行此操作,也很容易绕过,只需打开另一个浏览器(firefox而不是chrome),您将拥有一个完全不同的会话。会话对您不起作用,因为会话是特定于浏览器的(即它基于cookie,并且每个浏览器处理cookie的方式不同)。所以(正如我在其他地方提到的)您所要做的就是打开一个不同的浏览器来绕过任何会话安全性。但是,如果要使用会话,只需设置会话标志,然后将浏览器重定向到要下载的文件,这将确保在下载开始之前更新会话变量。您还需要将其与动态生成的唯一下载id相结合,以引用特定文件,然后,当下载开始时,您在数据库中将该id标记为已下载,并防止再次使用该id。