ASP.NET 程序中删除文件夹导致session失效问题的解决办法分享


在ASP.NET程序中,删除文件夹时导致Session失效的问题,主要是由于ASP.NET的默认行为会监视应用程序文件夹及其子文件夹的更改,以触发应用程序的重启来确保应用状态的一致性。当检测到文件或文件夹的删除、添加或修改时,这种监视机制可能会触发应用程序域(AppDomain)的重启,从而导致Session状态丢失。

以下是一些解决这一问题的办法:

### 1. 修改Session存储模式

**StateServer模式**:

将Session存储在IIS外部的独立Windows服务(aspnet_state.exe)中。这样,即使应用程序重启,Session数据也不会丢失。

- **启用ASP.NET状态服务**:在“控制面板”->“管理工具”->“服务”中,找到ASP.NET State Service服务并设置为自动启动。

- **配置Web.config**:在``节点中添加``配置,设置`mode="StateServer"`,并指定`stateConnectionString`以连接到状态服务。

示例代码(Web.config):


<system.web>
    <sessionState mode="StateServer"
                  stateNetworkTimeout="20"
                  stateConnectionString="tcpip=127.0.0.1:42424" />
</system.web>

**SqlServer模式**:

将Session存储在SQL Server数据库的表中。这种方式提供了更好的数据持久性和可伸缩性。

- **配置数据库**:使用aspnet_regsql.exe工具在SQL Server数据库中创建必要的表和存储过程。

- **配置Web.config**:同样在``节点中设置`mode="SQLServer"`,并指定数据库连接字符串。

### 2. 阻止文件夹监视

通过编程方式停止ASP.NET对特定文件夹的监视,以防止删除文件夹时触发重启。这通常涉及反射来访问并修改内部监控机制。

- **在Global.asax或HttpModule中设置**:使用反射来访问`HttpRuntime`的`FileChangesMonitor`属性,并调用`StopMonitoring`方法来停止对特定文件夹的监视。

示例代码(HttpModule或Global.asax中的Application_Start):


using System.Reflection;

public void Init()
{
    PropertyInfo p = typeof(HttpRuntime).GetProperty("FileChangesMonitor", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
    object o = p.GetValue(null, null);
    FieldInfo f = o.GetType().GetField("_dirMonSubdirs", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
    object monitor = f.GetValue(o);
    MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", BindingFlags.Instance | BindingFlags.NonPublic);
    m.Invoke(monitor, new object[] { });
}

### 3. 避免在应用程序文件夹中操作

如果可能,尽量避免在ASP.NET应用程序的根目录或受监视的文件夹中删除文件夹。可以将需要操作的文件或文件夹放在应用程序目录之外,并通过相对路径或虚拟目录来访问它们。

### 总结

解决ASP.NET程序中删除文件夹导致Session失效的问题,可以通过改变Session的存储方式(如使用StateServer或SqlServer模式),或通过编程方式阻止对特定文件夹的监视来实现。每种方法都有其适用场景和优缺点,需要根据具体的应用场景和需求来选择合适的解决方案。