为什么反射搜索会突然找不到任何东西?
我根据这个问题和答案有以下代码 如何获取 ASP.NET C# 中请求的文件的 MIME 类型? 它工作得非常好:
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
。
可能是什么原因?应用程序中没有任何特殊的更改,即使更改了,它如何影响包装类的构造函数?
I had the following code as per this question&answer How do I get the MIME type of a file being requested in ASP.NET C#?
and it was working perfectly fine:
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);
}
Now suddenly the mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic)
returns null
.
What could be the reason? Nothing special was changed in the application and even if it was, how could it influence this constructor for the wrapper class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的猜测是服务器上安装的 .NET Framework 已升级,并且私有构造函数在新版本下不再存在。
程序集开发人员(在本例中为 Microsoft)可以随心所欲地更改任何私有(或内部)类型或成员,而不会被视为重大更改。
编辑:我在.NET 4.0下检查了我的电脑,该方法仍然存在。这是它的签名:
此时,我的两个建议是在运行时检查您的实际 .NET 版本……
并枚举
MimeMapping
类的方法来检查它们是否符合您的期望:更新:好消息是
MimeMapping
类及其GetMimeMapping
方法看起来可能会在 .NET 4.5 中公开。但是,这意味着您的代码肯定会崩溃,因为您只搜索
NonPublic
方法。尝试执行全包搜索并查看GetMimeMapping
是否显示:My guess would be that the .NET Framework installed on the server got upgraded, and the private constructor is no longer present under the new version.
Assembly developers (in this case, Microsoft) are allowed to change any private (or internal) types or members at their whim, without it being considered to have been a breaking change.
Edit: I checked on my PC under .NET 4.0, and the method is still present. This is its signature:
At this point, my two suggestions would be to check your actual .NET version at runtime…
…and to enumerate the methods of the
MimeMapping
class to check whether they correspond to what you expect:Update: The good news is that the
MimeMapping
class and itsGetMimeMapping
method seem like they might be made public in .NET 4.5.However, this means that your code would definitely break, since you’re only searching for
NonPublic
methods. Try performing an all-inclusive search instead and see whetherGetMimeMapping
shows up:我自己刚刚遇到了这个问题,可以提供一些额外的背景信息:
Microsoft 对 dll 进行了半升级(例如将 MimeMapping 从“内部”更改为“公共”)。计划将这些更改完全纳入框架的下一版本。
在 .NET 4.0 及以上版本中,为了防止开发人员在较新的系统上使用这些修改(他们可能不知道它会在未打补丁的计算机上崩溃),IDE 在“参考程序集”文件夹中使用代码签名的快照(而不是运行时的程序集)来自 GAC),在主要版本之间不会发生变化。
这意味着尽管运行时类型是公共的,但您的 IDE 只能看到内部版本,因此您仍然无法在没有反射的情况下使用它。
您的代码只需更改以检查 Public 和 NonPublic 绑定标志,以满足正在使用的版本。在该框架的下一个版本中,您可能只能使用该类型而无需反射。
Just ran into this myself, and can give a little extra context:
Microsoft do demi-upgrades to dlls (such as changing MimeMapping from "internal" to "public"). The plan is that those changes go fully into the next version of the framework.
In .NET 4.0 onwards, to prevent developers from using these modifications on newer systems (who might not know it would break on unpatched computers), the IDE uses a snapshot of the code signatures in a "Reference Assemblies" folder (not the runtime ones from the GAC), which do not change between major versions.
This means that despite the runtime type being public, your IDE can only see the internal version, therefore you still cannot use it without reflection.
Your code needs to only change to check with both Public and NonPublic binding flags to cater for which ever version happens to be in use. In the next version of the framework, you will probably just be able to use the type without reflection.