3

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?

Community
  • 1
  • 1
mare
  • 13,033
  • 24
  • 102
  • 191

2 Answers2

5

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);
Douglas
  • 53,759
  • 13
  • 140
  • 188
  • it has something to do with my local workstation because I just tried it out and it works on the web server – mare Feb 04 '12 at 22:06
  • Try executing the two snippets above, and tell us what is the result of `version`, and the names of the methods returned in `methods`. – Douglas Feb 04 '12 at 22:09
  • I'm accepting this answer because it is the only logical explanation, something must have happened to my workstation's .NET Framework that it's not working anymore. – mare Feb 04 '12 at 22:09
  • well the runtime version is 4.0.30319 and the method returned is only one and it is {Void SetIntegratedApplicationContext(IntPtr)} – mare Feb 04 '12 at 22:15
  • Curious… I don’t get even a single Google hit for `SetIntegratedApplicationContext`. If you want to investigate, could you please try the all-inclusive `GetMethods` pasted above? – Douglas Feb 04 '12 at 22:32
  • i will tomorrow, will let you know – mare Feb 04 '12 at 22:38
  • 1
    the GetMethods() call does indeed find the method when using your expanded list of binding flags – mare Jun 21 '12 at 22:48
  • So the solution is to add Public to the `GetMimeMappingMethod = mimeMappingType.GetMethod("GetMimeMapping", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);` Note the **| BindingFlags.Public** – lko Mar 19 '13 at 07:34
  • @user878612: Yes. `BindingFlags.Public` instructs `Type.GetMethods` to include public methods (such as `GetMimeMapping` under .NET 4.5) in its results. – Douglas Mar 19 '13 at 07:56
  • That could/should be added to the answer as it's currently only troubleshooting (which leads to this solution) at this point... The answer itself is to include that single missing flag for the changed method access modifier in GetMimeMapping. – lko Mar 19 '13 at 08:25
0

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.

Lee
  • 1,591
  • 1
  • 14
  • 28