我有一个网站,我正在尝试通过WriteFile传送文件,它们在Chrome和Firefox中运行良好,但在IE中,我必须点击“重试”一次或两次才能实际下载文件。
以下是代码:
public class DownloadHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var r = context.Response;
r.Clear();
r.ClearContent();
r.ContentType = "application/octet-stream";
string path = "";
try
{
if (HttpContext.Current.Request.QueryString["n"] != null)
{
var file = HttpContext.Current.Request.QueryString["n"].ToString();
var type = HttpContext.Current.Request.QueryString["t"].ToString();
r.AddHeader("Content-Disposition", "attachment; filename=" + file.Substring(file.IndexOf('_')+1));
string folder = "";
switch (type.ToLower())
{
case "public":
folder = ConfigurationManager.AppSettings["BCD_PublicDocsLoc"];
break;
case "private":
folder = ConfigurationManager.AppSettings["BCD_PrivateDocsLoc"];
break;
case "internal":
folder = ConfigurationManager.AppSettings["BCD_InternalDocsLoc"];
break;
}
path = folder + "/" + file;
r.WriteFile(path);
r.Flush();
r.Close();
r.End();
}
}
catch (Exception ex)
{
r.Flush();
r.Close();
r.End();
context.Response.Redirect("Error.aspx?err=301");
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
如果有人对于为什么会这样做有任何建议,我们将不胜感激。谢谢!
答案 0 :(得分:2)
尝试使用 HttpApplication.CompleteRequest()替换 HttpResponse 的 Close()和 End()调用
Read here why,也有例子。
此外,对于与您类似的情况,建议here(在第一个答案中)提供此解决方案。
正如所暗示的那样,这篇文章中的一个小解释很方便,因为未来链接可能已经死亡,这里有:
简而言之:IE似乎遇到了 HttpResponse.Close 和 HttpResponse.End 方法的问题。除此之外,无论如何,Microsoft建议在大多数情况下使用 HttpApplication.CompleteRequest 而不是前两个,因为:
- HttpResponse.Close()突然终止连接,丢弃缓冲数据,不适用于需要响应客户端的正常HTTP使用
- HttpResponse.End()存在与旧版ASP技术兼容的原因。它直接调用EndRequest事件,并且在执行End调用后没有其他代码,这在许多情况下很不方便
- HttpApplication.CompleteRequest():还执行 EndRequest 事件,它允许执行 CompleteRequest 调用之后的代码,这使得处理大多数情况更合适。
答案 1 :(得分:0)
只是一种预感,但听起来像是一个I.E.缓存问题给我......
如果I.E设置为每次我访问网站时自动检查更新的页面。 (在[tools \ internet options \ general \ browsing history / settings]中)然后你不会有缓存问题。 就像我说的那样,只是预感,但是给它一个旋转。
如果您想绕过这个[* 1],请在查询字符串中添加一个guid。[* 2]
[* 1]缓存设置是按用户设置的用户,您永远不能抢占用户设置,因此请与他们合作
[* 2] nocache值总是不同,浏览器永远不会有缓存版本。
我使用这样的东西......
protected void Page_PreRender(object sender, EventArgs e)
{
if (HttpContext.Current.Request.QueryString["FirstRun"] == "1")
{
NameValueCollection nvc = HttpUtility.ParseQueryString(Request.Url.Query);
nvc.Remove("FirstRun");
string url = Request.Url.AbsolutePath;
for (int i = 0; i < nvc.Count; i++)
url += string.Format("{0}{1}={2}", (i == 0 ? "?" : "&"), nvc.Keys[i], nvc[i]);
Response.Redirect(string.Format("{1}&NoCache={0}",System.Guid.NewGuid().ToString().Replace("-",""),url));
}
}
此页面的任何链接/重定向都需要?FirstRun = 1(或&amp; FirstRun = 1)附加到查询字符串。一旦将&amp; noCache值添加到查询字符串,页面重新加载就会自行循环。
注意: 因为你添加了FirstRun = 1,它总是会在服务器端执行两次,但对你的用户和浏览器来说只是一次加载。
如果你没有添加FirstRun = 1,它将表现得像一个普通的请求,因为它永远不会进入这个状态。