为什么反射搜索突然找不到任何东西?

时间:2012-02-04 21:40:55

标签: c# reflection mime-types

根据此问题,我有以下代码并回答How do I get the MIME type of a file being requested in ASP.NET C#? 它工作得非常好:

    static MimeMappingWrapper()
    {
        // dirty trick - Assembly.LoadWIthPartialName has been deprecated        
        //Assembly ass = Assembly.LoadWithPartialName("System.Web");
        Assembly ass = Assembly.GetAssembly(typeof (HttpApplication));
        Type mimeMappingType = ass.GetType("System.Web.MimeMapping");

        GetMimeMappingMethod = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic);
    }

现在突然mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic)返回null

可能是什么原因?在应用程序中没有更改任何特殊内容,即使它是,它如何影响包装类的构造函数?

2 个答案:

答案 0 :(得分:5)

我的猜测是服务器上安装的.NET Framework已升级,私有构造函数不再出现在新版本下。

允许程序集开发人员(在本例中为Microsoft)随心所欲地更改任何私有(或内部)类型或成员,而不会将其视为重大变更。

编辑:我在.NET 4.0下检查了我的电脑,但该方法仍然存在。这是它的签名:

// System.Web.MimeMapping
internal static string GetMimeMapping(string FileName)

此时,我的两个建议是在运行时检查你的实际.NET版本......

var version = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();

...并枚举MimeMapping类的方法,以检查它们是否符合您的期望:

var methods = mimeMappingType.GetMethods(BindingFlags.Static | BindingFlags.NonPublic);

更新:好消息是MimeMapping类及其GetMimeMapping方法似乎可能会在.NET 4.5中公开。

但是,这意味着您的代码肯定会中断,因为您只搜索NonPublic方法。尝试执行全包搜索,看看GetMimeMapping是否显示:

var methods = mimeMappingType.GetMethods(
    BindingFlags.Instance | 
    BindingFlags.Static | 
    BindingFlags.Public |
    BindingFlags.NonPublic | 
    BindingFlags.FlattenHierarchy);

答案 1 :(得分:0)

我自己也遇到了这个问题,并且可以给出一些额外的背景:

微软对dll进行了半升级(例如将MimeMapping从“内部”更改为“公共”)。计划是这些更改完全进入下一版本的框架。

在.NET 4.0及更高版本中,为防止开发人员在较新的系统上使用这些修改(可能不知道它会在未修补的计算机上中断),IDE会在“参考装配”文件夹中使用代码签名的快照(不是来自GAC的运行时),主要版本之间不会发生变化。

这意味着尽管运行时类型是公共的,但您的IDE只能看到内部版本,因​​此如果没有反射,您仍然无法使用它。

您的代码只需更改为检查Public和NonPublic绑定标志,以满足正在使用的版本。在框架的下一个版本中,您可能只能使用没有反射的类型。