HttpRuntime CacheInternal NULL reference exception while reading user sessions (Reflection)
Asked Answered
U

3

4

After some updates on our windows servers(2008R2 ,2012) Asp.net application throwing error:

var obj_1 = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static); 

CacheInternal is coming null, dont know why ?

following solution is not working :( Solution

enter image description here

Underlying answered 11/7, 2017 at 16:57 Comment(2)
Possible duplicate of What is a NullReferenceException, and how do I fix it?Raceme
Looking at the latest reference source for HttpRuntime, I don't see a CacheInternal property. referencesource.microsoft.com/#System.Web/HttpRuntime.csAfrikander
U
4

I have find the solution. Now HTTPRuntime class doesnt have CacheInternal Property.So to achive the above task I have created a global list adding sessions in that list in Session_Start and removing the sessions in Sessions_end functions of Global.asax.

Underlying answered 18/7, 2017 at 16:59 Comment(1)
+1 , are you aware of any other alternative for this since my code is dependent on CacheInternal? Because I am trying to dispose other sessionsUmber
L
4

I have find a solution that maybe is the best for now. If anyone has another, let me know!

  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.
    // https://stackoverflow.com/a/45045160
    // 
    // 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;

Regards!

Leah answered 3/10, 2017 at 22:23 Comment(0)
F
2

That internal member was present in .NET 2.0 and disappeared somewhere between .NET 3.5 and .NET 4.6.1. That's why you shouldn't use reflection to rely on nonpublic members. They can disappear or be renamed any time.

Because .NET is backwards compatible, forcing a certain runtime version will not use older assemblies at runtime, if newer ones are available: .NET 4.6.1 is still an in-place upgrade of all earlier versions down to 4.0.

So I think this update either patched the member away from the System.Web assembly, or it was never in 4.0 to begin with and your application pool somehow changed from .NET 2.0 to .NET 4.0.

Of course it isn't advisable to uninstall updates, but you could try to find the one removing this member. You'd then have to verify it wasn't a security update.

Alternatively force the application to run under .NET 2.0, if that's viable.

You could also try to find a different way to solve the original problem.

Felixfeliza answered 11/7, 2017 at 22:1 Comment(1)
I have find the solution. Now HTTPRuntime class doesnt have CacheInternal Property.So to achive the above task I have created a global list adding sessions in that list in Session_Start and removing the sessions in Sessions_end functions of Global.asax.Underlying

© 2022 - 2024 — McMap. All rights reserved.