使用HttpResponse.WriteFile单击文件下载所需的重试

时间:2015-01-14 16:00:18

标签: c# internet-explorer

我有一个网站,我正在尝试通过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;
        }
    }
}

如果有人对于为什么会这样做有任何建议,我们将不胜感激。谢谢!

2 个答案:

答案 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,它将表现得像一个普通的请求,因为它永远不会进入这个状态。