文件上传或多文件上传,不能访问已关闭的文件

异常:System.ObjectDisposedException: Cannot access a closed file.

错误指向:读取流的内容语句 stream.Read(byteArr, 0, byteArr.Length);

当然,这里没有使用流来操作上传文件的,使用HttpContext.Request.Files[i].SaveAs(),也会出现这个问题。解决方案同下。

/// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="inputStream">上传的文件流</param>
        /// <param name="filePath">上传文件的保存路径</param> 
        /// <param name="msg">错误信息</param>
        /// <returns></returns>
        public static bool SaveFile(Stream inputStream, string filePath, out string msg)
        {
            try
            {
                LogUtil.Info("文件上传操作类FileUpLoad,上传文件到服务器:SaveFile(),文件保存路径" + filePath);
                if (Directory.Exists(filePath))
                {
                    msg = "文件已存在";
                    return false;
                }
                byte[] byteArr = new byte[inputStream.Length];
                Stream stream = inputStream;
                stream.Read(byteArr, 0, byteArr.Length);
                using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write))
                {
                    fs.Write(byteArr, 0, byteArr.Length);
                }
                msg = string.Empty;
                return true;
            }
            catch (Exception ex)
            {
                msg = ex.Message;
                //return false;
                LogUtil.Error("文件上传操作类FileUpLoad,上传文件到服务器:SaveFile()异常",ex);
                throw ex;
            }
        }
View Code

搜索网上解决方案;

在web.config中添加

<httpRuntime executionTimeout="90" maxRequestLength="2097151" useFullyQualifiedRedirectUrl="false" requestLengthDiskThreshold="8192"/>

当然也有部分兄台说不能解决此问题的。这里我们不讨论,问题因人而异。我们就事论事。

根据此解决方案,我们来查询这些设置的作用。

官方文档:

httpRuntime的所有设置字段列出:

属性

 
属性说明

apartmentThreading

可选的 Boolean 属性。

启用单元线程处理以实现传统的 ASP 兼容性。

此属性是 .NET Framework 2.0 版中的新属性。默认值为 False

appRequestQueueLimit

可选的 Int32 属性。

指定 ASP.NET 将为应用程序排队的请求的最大数目。当没有足够的自由线程来处理请求时,将对请求进行排队。当队列超出了该属性中指定的限制时,将通过“503 - 服务器太忙”错误信息拒绝传入的请求。

默认值为 5000。

Note注意

在 .NET Framework 1.0 版和 1.1 版中,默认值为 100。

delayNotificationTimeout

可选的 TimeSpan 属性。

指定延迟通知的超时时间。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为“00:00:05”(5 秒)。

enable

可选的 Boolean 属性。

指定是否在当前的节点及子节点级别启用应用程序域 (AppDomain),以接受传入的请求。如果为 False,则实际上关闭了该应用程序。

默认值为 True

enableHeaderChecking

可选的 Boolean 属性。

指定 ASP.NET 是否应检查请求标头,以检测可能的注入式攻击。如果检测到攻击,ASP.NET 将返回错误作为响应。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为 True

enableKernelOutputCache

可选的 Boolean 属性。

指定是否启用输出缓存。该属性只有在安装 Microsoft Internet 信息服务 (IIS) 6.0 或更高版本之后才起相应的作用。输出缓存的配置和请求的类型决定了是否对内容进行缓存。

若要对响应进行缓存,必须满足以下条件:

  • 必须通过页指令或使用缓存 API 显式启用缓存。

  • 缓存必须具有过期策略,以便内核知道何时放弃响应。

  • 缓存不能有任何可变标头或参数。

  • 不需要身份验证。

默认值为 True

enableVersionHeader

可选的 Boolean 属性。

指定 ASP.NET 是否应输出版本标头。Microsoft Visual Studio 2005 使用该属性来确定当前使用的 ASP.NET 版本。对于生产环境,该属性不是必需的,可以禁用。

Note注意

该属性在 .NET Framework 1.0 版中不可用。

默认值为 True

executionTimeout

可选的 TimeSpan 属性。

指定在被 ASP.NET 自动关闭前,允许执行请求的最大秒数。

只有当 compilation 元素中的调试属性为 False 时,此超时属性才适用。若要帮助避免在调试期间关闭应用程序,请不要将此超时属性设置为较大值。

Note注意

在 .NET Framework 1.0 版和 1.1 版中,默认值为 90。

默认值为“00:01:50”(110 秒)。

maxRequestLength

可选的 Int32 属性。

指定输入流缓冲阈值限制(以 KB 为单位)。此限制可用于防止拒绝服务攻击;例如,因用户向服务器发送大型文件而导致的拒绝服务攻击。

默认值为 4096 (4 MB)。

maxWaitChangeNotification

可选的 Int32 属性。

指定从第一次文件更改通知开始,在为新请求重新启动 AppDomain 之前等待的最长时间(秒)。将此属性设置为一个大于完成任何文件复制过程所需时间的数值。根据该属性和 waitChangeNotification 属性的值来合并文件更改通知。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为 0

minFreeThreads

可选的 Int32 属性。

指定允许执行新请求的自由线程的最小数目。ASP.NET 为要求附加线程来完成其处理的请求而使指定数目的线程保持自由状态。

默认值为 8

minLocalRequestFreeThreads

可选的 Int32 属性。

指定 ASP.NET 保持的允许执行新本地请求的自由线程的最小数目。这一指定的线程数目是为从本地主机传入的请求而保留的,以防某些请求在其处理期间发出对本地主机的子请求。这有助于避免可能的因递归重新进入 Web 服务器而导致的死锁。

默认值为 4

requestLengthDiskThreshold

可选的 Int32 属性。

指定输入流缓冲阈值限制(以字节为单位)。该值不应超过 maxRequestLength 属性。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为 256

   

requireRootedSaveAsPath

可选的 Boolean 属性。

指定 SaveAs 方法中的 filename 参数是否必须为绝对路径。ASP.NET 进程必须具有在指定位置中创建文件的权限。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为 True

sendCacheControlHeader

可选的 Boolean 属性。

指定是否发送默认情况下设置为 Private 的缓存控制标头。如果为 True,则客户端缓存被禁用。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为 True

shutdownTimeout

可选的 TimeSpan 属性。

指定允许辅助进程关闭的分钟数。在达到该超时时间时,ASP.NET 关闭辅助进程。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为 "00:01:30"(90 秒)。

useFullyQualifiedRedirectUrl

可选的 Boolean 属性。

指示客户端重定向是否是完全限定的(采用 "http://server/path" 格式,这是某些移动控件所必需的),或者指示是否代之以将相对重定向发送到客户端。如果为 True,则所有不是完全限定的重定向都将自动转换为完全限定的格式。

Note注意

如果为 False,则某些浏览器在加载无 Cookie 会话中的页时可能会遇到问题。

默认值为 False

waitChangeNotification

可选的 Int32 属性。

指定重新启动 AppDomain 之前等待另一次文件更改通知的时间(以秒为单位)。将此属性设置为一个大于两次文件复制更改通知更新之间的时间的数值。根据该属性和 maxWaitChangeNotification 属性的值来合并文件更改通知。

此属性是 .NET Framework 2.0 版中的新属性。

默认值为 0 秒。

子元素

无。

父元素

 
元素说明

configuration

公共语言运行库和 .NET Framework 应用程序所使用的每个配置文件中均需要的根元素。

system.web

指定配置文件中 ASP.NET 配置设置的根元素,并且包含各种配置元素,这些配置元素配置 ASP.NET Web 应用程序并控制这些应用程序的行为方式。

根据上面的介绍,进过实验,发现:

executionTimeout="90" maxRequestLength="2097151" 此两个属性设置文件大小和请求超时,如果不设置

requestLengthDiskThreshold="8192" ,则仍然上传不成功,报上面的错误。

当然属性值的大小,在范围内,根据需要设置。

useFullyQualifiedRedirectUrl="false" 这个属性设置貌似没有影响。有没有无所谓。

总结:本解决方案适合本人的情况。不能解决问题的朋友自行研究。

这里另外说一点,本人当时在设置这些属性时,因为只设置了executionTimeout="90" maxRequestLength="2097151" 这两个属性,然后没有成功,就放弃了

以后的设置,去研究其他的解决方案,以为这个解决方案是不行的,最后证明是完全可行的,可是绕了一个大圈子,浪费了很多时间。所以说,在解决问题时,一定要

严谨,仔细,不要浮躁,想当然。

原文地址:https://www.cnblogs.com/LL-723/p/3487731.html