无法使用反射访问运行时缓存

时间:2018-11-07 23:50:16

标签: asp.net-mvc caching reflection

根据此答案,我正在尝试获取HttpRuntime.Cache对象的到期日期:

https://stackoverflow.com/a/350374/1778169

方法是:

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;
}

当我尝试使用上述方法时,第一行将无法编译:

  

object.GetType()需要对象引用

如果我将Cache.GetType()替换为HttpRuntime.Cache.GetType(),则会进行编译,但是我从此部分返回null:

cacheType.GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic)

我在做什么错了?

我正在使用.NET 4.5。 System.Web.Caching是版本4.0.0.0。

1 个答案:

答案 0 :(得分:2)

您应该已经使用website Microsoft设置查找了原始源,以便找到HttpRuntime类的更多详细信息,特别是Cache属性。如果您查看line 2794 of the System.Web.HttpRuntime class,则可以看到Cache属性的以下定义:

 public static Cache Cache {
        get {
              ...
        }
 }

现在,由于属性为static,因此您不能使用正在使用的绑定标志,因为现在您正在寻找属于NonPublic的{​​{1}}成员。在.NET中,静态变量不属于实例,因此,您发布的代码将导致引发异常。它根本找不到您要查找的成员,因为它在您提供的实例中不存在-但是它确实存在于您要研究的类(Instance)的类型定义中。

为了使您的代码正常工作,您将需要省略绑定标志,处理您的请求的内部.NET代码现在可以理解,我们正在尝试查找静态方法:HttpRuntime。注意:如果要具有绑定标志(可读性,可理解性),则可以添加:HttpRuntime.Cache.GetType().GetMethod("Get"),其作用与省略标志时完全相同。

如果要执行该方法并获取结果(获取实际的BindingFlags.Public | BindingFlags.Static),则可以使用Cache调用刚从MethodDefinition收到的GetMethod