ASP .Net MVC下载错误并需要回收IIS应用程序池

时间:2017-06-15 08:10:51

标签: c# asp.net asp.net-mvc asp.net-mvc-4 iis

我目前维护着一个近3年的ASP .Net MVC网站,该应用程序运行在 IIS(现在在IIS 7中)上并使用 ASP .Net 4 Framework 。它几乎每天都被客户端使用,并且有很多上传下载文件交易。它还使用 ELMAH 作为未处理的异常处理。应用程序运行良好,直到几个月,有很多来自用户的报告,他们无法下载文件,但没有任何错误消息,下载过程只是没有做任何事情,而浏览器控制台也没有日志。在进行多次检查后,所有具有下载功能的菜单都使用http响应

        Response.Clear();
        Response.Cache.SetCacheability(HttpCacheability.Private);
        Response.Expires = -1;
        Response.Buffer = true;

        Response.ContentType = "application/octet-stream";
        Response.AddHeader("Content-Length", Convert.ToString(file_in_bytes.Length));

        Response.AddHeader("Content-Disposition"
                   , string.Format("{0};FileName=\"{1}\"", "attachment", fileName));
        Response.AddHeader("Set-Cookie", "fileDownload=true; path=/");

        Response.BinaryWrite(hasil);
        Response.End();

似乎没有错(开发服务器中没有编译或运行时错误)。我们还检查了Elmah的日志,但没有出现相关的错误消息。在我们的服务器管理团队在IIS中回收应用程序池之后,此问题暂时消失

此Web也与另一个Web共享应用程序池,当发生该错误时,两个应用程序都受到影响,仅受影响的下载功能,另一个功能如数据从数据库检索,插入/编辑/删除数据工作正常。

我还检查了Web服务器事件查看器,但那里没有任何错误。对我们来说非常奇怪的是,在我们回收应用程序池后,此错误暂时消失,几天或几周或几个月之后,错误突然再次出现。

是否有任何我们错过的日志?或者下载代码可能有问题? 为什么它在回收应用程序池之后暂时修复了?

另一个注意事项:用户需要下载的数据为平均500kb到2MB ,zip格式包含多个PDF文件

更新:经过几个小时的调查,我发现这个Web应用程序使用不同的方法下载,有些正在使用Http.Response上面的代码,有些则使用FileContentResult作为返回值。但是在客户端使用jquery.FileDownload。我还在几个在这个应用程序中有下载文件方法的Controller中找到了这个方法,

private void CheckAndHandleFileResult(ActionExecutedContext filterContext) 
{
    var httpContext = filterContext.HttpContext;
    var response = httpContext.Response;

    if (filterContext.Result is FileContentResult)
    {
        //jquery.fileDownload uses this cookie to determine that 
        //a file download has completed successfully
        response.AppendCookie(new HttpCookie(CookieName, "true") 
            { Path = CookiePath });
    }
    else
    {
        //ensure that the cookie is removed in case someone did 
        //a file download without using jquery.fileDownload
        if (httpContext.Request.Cookies[CookieName] != null)
        {
            response.AppendCookie(new HttpCookie(CookieName, "true") 
                { Expires = DateTime.Now.AddYears(-1), Path = CookiePath });
        }
    }
}

实际上我不确定该方法是否与此错误相关,但是在覆盖 System.Web.MVC.Controller OnActionExecuted 的方法中调用它,并且它包含该行如果使用FileContentResult,则为文件下载添加Cookie;如果不使用FileContentResult则删除Cookie,并且文件Download Cookie存在。如果Cookie在创建后意外未被删除/清除,则可能存在?并且因为下载方法经常被每天近100个用户调用,所以Cookie可能堆积起来并导致IIS工作进程崩溃?

我还检查了一些关于Cookie及其与IIS会话状态(使用In-Proc状态的我的应用程序)的关系的引用。我关闭了吗?或者我错过了什么?

1 个答案:

答案 0 :(得分:0)

为什么Response.Buffer设置为true?启用缓冲后,仅在完成所有处理后才会发送响应。你可以通过设置为false来禁用它,看看这是否有效?这可能是必须回收应用程序池的原因。您还可以检查是否遇到这些问题 - Help link