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?
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:
// System.Web.MimeMapping
internal static string GetMimeMapping(string FileName)
At this point, my two suggestions would be to check your actual .NET version at runtime…
var version = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();
…and to enumerate the methods of the MimeMapping
class to check whether they correspond to what you expect:
var methods = mimeMappingType.GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
Update: The good news is that the MimeMapping
class and its GetMimeMapping
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 whether GetMimeMapping
shows up:
var methods = mimeMappingType.GetMethods(
BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.FlattenHierarchy);
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.