我有一个ASP.Net Web应用程序,允许用户将文件上传到与Web应用程序位于同一虚拟目录中的uploads
目录。每个上载的文件都进入一个以用户会话ID命名的临时子目录。完成文件后,我删除了临时子目录。唯一的问题是当删除子目录时,AppDomain
会被回收并杀死所有用户会话(使用inproc
会话状态)。罪魁祸首似乎是一个FileChangesMonitor
,它监视应用程序中所有子目录的变化。
以下代码在Windows Server 2003上运行的IIS 6.0中运行良好,以禁用子目录的FileChangesMonitor
,但由于某种原因,它在Windows Server 2008上的IIS 7.0中不起作用:
System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
object o = p.GetValue(null, null);
System.Reflection.FieldInfo f = o.GetType().GetField("_dirMonSubdirs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase);
object monitor = f.GetValue(o);
System.Reflection.MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
m.Invoke(monitor, new object[] { });
我发现另一个解决方案,完全禁用FileChangesMonitor
here。但这不是理想的解决方案,因为我仍然希望监视除uploads
目录中的temp子目录之外的所有其他文件。
为什么这在IIS 6.0中有效,而在IIS 7.0中无效?
在IIS 7.0中,您可以在要禁用回收的虚拟文件夹中指定子目录吗?
有没有其他方法可以不使用反射来做到这一点?
@fyjham是对的,你需要将你的上传文件夹移到webroot
之外。如果这是一个面向公众的网站,那么将其置于webroo
t之下就是一个安全风险。
为了回答我自己的问题,我使用IIS 7.0并发现当应用程序池上的托管管道模式设置为“集成”时,上面的反射代码不起作用。确保将应用程序池的托管管道模式设置为“经典”。
也似乎无法通过IIS手动禁用此功能。