读取用户会话时 HttpRuntime CacheInternal NULL 引用异常(反射)
HttpRuntime CacheInternal NULL reference exception while reading user sessions (Reflection)
在我们的 windows 服务器(2008R2,2012)上进行一些更新后 Asp.net 应用程序抛出错误:
var obj_1 = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static);
CacheInternal 即将变为空,不知道为什么?
以下解决方案不起作用:(
Solution
该内部成员出现在 .NET 2.0 中,在 .NET 3.5 和 .NET 4.6.1 之间消失了。这就是为什么您不应该使用反射来依赖非公共成员。它们可以随时消失或重命名。
因为 .NET 是向后兼容的,强制某个 运行 时间版本将不会在 运行 时间使用旧程序集,如果有更新的程序集:.NET 4.6.1 仍然是一个-将所有早期版本升级到 4.0。
所以我认为此更新要么从 System.Web 程序集修补了成员,要么从一开始就从不在 4.0 中并且您的应用程序池以某种方式从 .NET 2.0 更改为 .NET 4.0。
当然不建议卸载更新,但您可以尝试找到删除该成员的那个。然后您必须验证它不是安全更新。
或者强制应用程序在 .NET 2.0 下 运行,如果可行的话。
您也可以尝试另辟蹊径解决原来的问题。
我已经找到解决办法了。现在 HTTPRuntime class 没有 CacheInternal Property.So 来完成上述任务 我创建了一个全局列表,在 Session_Start 的列表中添加会话并删除 Sessions_end 函数中的会话 Global.asax.
我找到了一个可能是目前最好的解决方案。如果有人有另一个,请告诉我!
object aspNetCacheInternal = null;
var cacheInternalPropInfo = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static);
if (cacheInternalPropInfo == null)
{
// At some point, after some .NET Framework's security update, that internal member disappeared.
//
//
// We need to look for internal cache otherwise.
//
var cacheInternalFieldInfo = HttpRuntime.Cache.GetType().GetField("_internalCache", BindingFlags.NonPublic | BindingFlags.Static);
if (cacheInternalFieldInfo != null)
{
var httpRuntimeInternalCache = cacheInternalFieldInfo.GetValue(HttpRuntime.Cache);
var httpRuntimeInternalCacheField = httpRuntimeInternalCache.GetType().GetField("_cacheInternal", BindingFlags.NonPublic | BindingFlags.Instance);
if (httpRuntimeInternalCacheField != null)
aspNetCacheInternal = httpRuntimeInternalCacheField.GetValue(httpRuntimeInternalCache);
}
}
else
{
aspNetCacheInternal = cacheInternalPropInfo.GetValue(null, null);
}
return aspNetCacheInternal;
此致!
在我们的 windows 服务器(2008R2,2012)上进行一些更新后 Asp.net 应用程序抛出错误:
var obj_1 = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static);
CacheInternal 即将变为空,不知道为什么?
以下解决方案不起作用:( Solution
该内部成员出现在 .NET 2.0 中,在 .NET 3.5 和 .NET 4.6.1 之间消失了。这就是为什么您不应该使用反射来依赖非公共成员。它们可以随时消失或重命名。
因为 .NET 是向后兼容的,强制某个 运行 时间版本将不会在 运行 时间使用旧程序集,如果有更新的程序集:.NET 4.6.1 仍然是一个-将所有早期版本升级到 4.0。
所以我认为此更新要么从 System.Web 程序集修补了成员,要么从一开始就从不在 4.0 中并且您的应用程序池以某种方式从 .NET 2.0 更改为 .NET 4.0。
当然不建议卸载更新,但您可以尝试找到删除该成员的那个。然后您必须验证它不是安全更新。
或者强制应用程序在 .NET 2.0 下 运行,如果可行的话。
您也可以尝试另辟蹊径解决原来的问题。
我已经找到解决办法了。现在 HTTPRuntime class 没有 CacheInternal Property.So 来完成上述任务 我创建了一个全局列表,在 Session_Start 的列表中添加会话并删除 Sessions_end 函数中的会话 Global.asax.
我找到了一个可能是目前最好的解决方案。如果有人有另一个,请告诉我!
object aspNetCacheInternal = null;
var cacheInternalPropInfo = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static);
if (cacheInternalPropInfo == null)
{
// At some point, after some .NET Framework's security update, that internal member disappeared.
//
//
// We need to look for internal cache otherwise.
//
var cacheInternalFieldInfo = HttpRuntime.Cache.GetType().GetField("_internalCache", BindingFlags.NonPublic | BindingFlags.Static);
if (cacheInternalFieldInfo != null)
{
var httpRuntimeInternalCache = cacheInternalFieldInfo.GetValue(HttpRuntime.Cache);
var httpRuntimeInternalCacheField = httpRuntimeInternalCache.GetType().GetField("_cacheInternal", BindingFlags.NonPublic | BindingFlags.Instance);
if (httpRuntimeInternalCacheField != null)
aspNetCacheInternal = httpRuntimeInternalCacheField.GetValue(httpRuntimeInternalCache);
}
}
else
{
aspNetCacheInternal = cacheInternalPropInfo.GetValue(null, null);
}
return aspNetCacheInternal;
此致!