C# 如何确保网页等待上载完成?
我有以下代码,用于将大型文件(~6MB)上载到ASP.NETMVC2应用程序。上传文件后,可能需要5分钟才能从控制器返回响应 在此期间,IE9没有显示任何处理尚未完成的迹象,即用户可以选择其他文件并重新发布 如何通知用户操作未完成,并在旧文件处理完成之前禁用“提交”按钮C# 如何确保网页等待上载完成?,c#,asp.net-mvc,asp.net-mvc-2,C#,Asp.net Mvc,Asp.net Mvc 2,我有以下代码,用于将大型文件(~6MB)上载到ASP.NETMVC2应用程序。上传文件后,可能需要5分钟才能从控制器返回响应 在此期间,IE9没有显示任何处理尚未完成的迹象,即用户可以选择其他文件并重新发布 如何通知用户操作未完成,并在旧文件处理完成之前禁用“提交”按钮 <% using (Html.BeginForm("InvoiceImport", "Grid", FormMethod.Post, new { enctype = "multipart/f
<% using (Html.BeginForm("InvoiceImport", "Grid",
FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<input name="uploadFile" type="file" />
<input type="submit" name='invoice' value='Read'/>
<%} %>
更新
我认为最重要的问题是防止重复提交。
我尝试了下面的代码以防止重复提交,但由于未知原因,会话[“上载”]为空
如果第二次按下提交按钮。
如何防止重复提交
View added
<% if (TempData["Message"]!=null) { %>
setTimeout( function() {
showMessage ( '<%= TempData["Message"] as string %>');
}, 300 );
<% } %>
Controller
ActionResult ImportFromFile(HttpPostedFileBase uploadFile)
{
if (Session["Upload"] != null)
{
// todo: why this point is never reached ?
TempData["Message"] = Session["Upload"] + " Please wait file is being processed";
return View();
}
Session.Add("Upload", uploadFile.FileName);
Server.ScriptTimeout = 30 * 60;
ImportFromFile(uploadFile.InputStream);
TempData["Message"] = uploadFile.FileName + " completed";
Session.Remove("Upload");
return RedirectToAction("Complete");
}
添加了视图
setTimeout(函数(){
showMessage(“”);
}, 300 );
控制器
ActionResult ImportFromFile(HttpPostedFileBase上载文件)
{
如果(会话[“上载”]!=null)
{
//todo:为什么这一点从未达到?
TempData[“Message”]=会话[“Upload”]+“请稍候文件正在处理”;
返回视图();
}
添加(“上载”,uploadFile.FileName);
Server.ScriptTimeout=30*60;
ImportFromFile(uploadFile.InputStream);
TempData[“Message”]=uploadFile.FileName+“completed”;
删除(“上传”);
返回重定向到操作(“完成”);
}
> p>您应该考虑使用异步控制器。< /P>
这样,它将在一个单独的线程中运行上传,页面将不再锁定
查看以下链接:
使用异步调用时,向用户显示调用正在进行。查看博客文章了解长轮询,它允许您在进程结束时进行返回的调用
向用户显示他们已提交表单并禁用提交按钮
进行Ajax调用以实际进行调用并进行上传
完成后,通知用户作业已完成
如果您担心他们会刷新页面,从而能够再次提交,您需要在后端跟踪他们的提交状态。某种类型的锁定,以便您知道用户有正在运行的上载,并且他们不应该能够再次上载。考虑使用一些ajaxified上载解决方案,您将能够向用户显示过程的进度,直到完成为止
所以答案给出了使用ajax上传的详细示例。我个人喜欢这个解决方案。因此,这应该是一个好方法。解决问题的最简单方法是使用javascript禁用按钮和字段。在我们的页面中有像jQuery这样的javascript库吗
$('form').submit(function(){
$(this).find('input').prop('disabled', true)
});
对于jQuery,类似这样的情况。如果您有多个表单,您可能希望向表单中添加一个id,以仅针对此表单
更新:
对于重新提交的问题,没有绝对简单的解决方案:
以避免F5问题。确保在发布后重定向。你知道,但我想如果需要很长时间,他们可能会同时按F5
我脑子里有一些解决这个问题的办法
- (如果您使用的是SQL)生成一个guid,并将其放置在表单页面的隐藏字段中。将此列设置为数据库中唯一的列,并将其与其余信息一起插入。如果他们试图重新提交,SQL将通过抛出一个您可以处理的异常来保护您
- 上述技术还有其他替代方法。也许您将这些guid存储在一个单独的表中,并对照该表进行检查,或者在XML或cache中进行检查
- 提交表单时,使用javascript添加时间戳。您在服务器上要做的第一件事是确保您在单击按钮后的x秒内
- 在提交时(第一次提交后),您可以使用javascript添加警告
window.onbeforeunload=函数(){return'已保存!请按no';}
最后一种解决方案虽然不安全,但很容易添加。比您更安全。使用Jquery和jqueryUI。最重要的问题是防止重复提交。使用cam按F5键并选择重试。jquery无法阻止此操作。我更新了问题并添加了代码,该代码应该阻止重复提交,但失败了。如何解决此问题?更新了答案并提供了一些建议。是否可以将会话[]用作问题的更新部分?为什么失败?您正在删除值:Session.Remove(“上载”);默认情况下,ASP.NET不会对同一会话并行执行两个请求。第二个请求将在第一个请求完成后运行,然后您已经删除了该请求value@MikaelEliasson我确实在状态上找到了这个,见最后一部分关于并发读取。我想他有可能以只读模式读取状态。他必须进行ajax调用来设置会话变量中的值,并确保线程已完成。然后使用只读参数调用upload和status方法。谢谢。如果按F5并重试,Ajax无法防止重复提交。我在问题的更新部分尝试了代码,但失败了。如何防止重复提交?非常感谢。是的,重复提交问题似乎是最重要的。由于会话密钥未保存在会话中,我尝试使用会话buit失败,原因不得而知。如何解决这个问题?我更新了问题。@安德鲁斯,你能调试并告诉我会话[“Upload”]的值是多少吗?当你希望它输入if语句时?在Session.Add(“Upload”,uploadFile.FileName)之后代码>会话[“上载”]
包含文件名。如果我将断点放在导入文件的开头,然后按F5键,则会话[“上载”]
为空。下一次调用中似乎没有传递会话变量。如何解决这个问题?@Andus,
$('form').submit(function(){
$(this).find('input').prop('disabled', true)
});