Is it possible to get the expiry DateTime
of an HttpRuntime.Cache
object?
If so, what would be the best approach?
I just went through the System.Web.Caching.Cache in reflector. It seems like everything that involves the expiry date is marked as internal. The only place i found public access to it, was through the Cache.Add and Cache.Insert methods.
So it looks like you are out of luck, unless you want to go through reflection, which I wouldn't recommend unless you really really need that date.
But if you wish to do it anyway, then here is some code that would do the trick:
private DateTime GetCacheUtcExpiryDateTime(string cacheKey)
{
object cacheEntry = Cache.GetType().GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Cache, new object[] { cacheKey, 1 });
PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires", BindingFlags.NonPublic | BindingFlags.Instance);
DateTime utcExpiresValue = (DateTime)utcExpiresProperty.GetValue(cacheEntry, null);
return utcExpiresValue;
}
Since .NET 4.5 the internal public getter of the HttpRuntime.Cache
was replaced with a static variant and thus you will need to invoke/get the static variant:
object cacheEntry = Cache.GetType().GetMethod("Get").Invoke(null, new object[] { cacheKey, 1 });
As suggested by someone in comments that the accepted answer does not work in .NET 4.7
I had a lot of trouble trying to figure out what changes needs to be done to make it work in .NET 4.7
Here's my code for people using .NET 4.7
private DateTime GetCacheUtcExpiryDateTime(string cacheKey)
{
var aspnetcachestoreprovider = System.Web.HttpRuntime.Cache.GetType().GetProperty("InternalCache", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(System.Web.HttpRuntime.Cache, null);
var intenralcachestore = aspnetcachestoreprovider.GetType().GetField("_cacheInternal", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aspnetcachestoreprovider);
Type TEnumCacheGetOptions = System.Web.HttpRuntime.Cache.GetType().Assembly.GetTypes().Where(d => d.Name == "CacheGetOptions").FirstOrDefault();
object cacheEntry = intenralcachestore.GetType().GetMethod("DoGet", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Any, new[] { typeof(bool), typeof(string), TEnumCacheGetOptions }, null).Invoke(intenralcachestore, new Object[] { true, cacheKey, 1 }); ;
PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires", BindingFlags.NonPublic | BindingFlags.Instance);
DateTime utcExpiresValue = (DateTime)utcExpiresProperty.GetValue(cacheEntry, null);
return utcExpiresValue;
}
And for those who wants the code to function in multiple different environments (sandbox using .NET 4.5 and production using .NET 4.7), here's some patch work:
private DateTime GetCacheUtcExpiryDateTime(string cacheKey)
{
MethodInfo GetCacheEntryMethod = null;
Object CacheStore = null;
bool GetterFound = true;
GetCacheEntryMethod = System.Web.HttpRuntime.Cache.GetType().GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic);
if (GetCacheEntryMethod != null)
{
GetterFound = true;
CacheStore = System.Web.HttpRuntime.Cache;
}
else
{
var aspnetcachestoreprovider = System.Web.HttpRuntime.Cache.GetType().GetProperty("InternalCache", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(System.Web.HttpRuntime.Cache, null);
var intenralcachestore = aspnetcachestoreprovider.GetType().GetField("_cacheInternal", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aspnetcachestoreprovider);
Type TEnumCacheGetOptions = System.Web.HttpRuntime.Cache.GetType().Assembly.GetTypes().Where(d => d.Name == "CacheGetOptions").FirstOrDefault();
GetCacheEntryMethod = intenralcachestore.GetType().GetMethod("DoGet", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Any, new[] { typeof(bool), typeof(string), TEnumCacheGetOptions }, null);
GetterFound = false;
CacheStore = intenralcachestore;
}
dynamic cacheEntry;
if (GetterFound)
cacheEntry = GetCacheEntryMethod.Invoke(CacheStore, new Object[] { cacheKey, 1 });
else
cacheEntry = GetCacheEntryMethod.Invoke(CacheStore, new Object[] { true, cacheKey, 1 });
PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires", BindingFlags.NonPublic | BindingFlags.Instance);
DateTime utcExpiresValue = (DateTime)utcExpiresProperty.GetValue(cacheEntry, null);
return utcExpiresValue;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With