locked
"Could not load file or assembly" error when referencing HttpModule using partial name RRS feed

  • Question

  • User51841393 posted

    I have a .NET 4.0 32 bit web application where I reference an HttpModule in the web.config. The assembly which contains the HttpModule is in the GAC. The reference to the HttpModule uses a partial name since our assembly versions always change with every release and I do not want to have to modify the web.config for every release. The HttpModule is loaded from the GAC just fine in my application however if I have a sub application then I get the "Could not load file or assembly" error. If I place the assembly in the bin directory of the sub application or if I include the version number in the HttpModule reference in the root application's web.config then it loads the assembly from the GAC just fine. I used Fusion Log Viewer to confirm that it is loaded from the GAC. From my investigation it appears that it always needs the fully qualified name in order to find the assembly in the GAC. I *think* it works fine in my root application because it reads the version number from the assembly in the bin and then uses that info to do the fully qualified name lookup in the GAC. Perhaps I was under the wrong impression but why can't the assembly in my sub application be loaded from the GAC using a partial name? 

    This is the HttpModule reference in root application's web.config:

    <add name="MyCookieModule" type="My.CustomHttpModules.MyCookieModule, My.CustomHttpModules, Culture=neutral, PublicKeyToken=7337ad9038z63n2a"/>

    Tuesday, October 22, 2013 6:04 PM

All replies

  • User2019981500 posted

    Hi

     

    .NET application loads types from the root webapplication BIN directory . I believe if type is not in root directory then it won't be able to create instances of them.

    May be you can try Create an application/virtual directory from the sub-directory or Move the required assemblies to the /bin directory of the main web app.

    REMMONEDATION FROM MICRSOFT

    FYI :-

    Avoid Binding on Partial Assembly Names

     


     

    Partial name binding occurs when you specify only part of the assembly display name (FullName) when you load an assembly. For example, you might call the Assembly.Load method with only the simple name of the assembly, omitting the version, culture, and public key token. Or you might call the Assembly.LoadWithPartialName method, which first calls the Assembly.Load method and, if that fails to locate the assembly, searches the global assembly cache and loads the latest available version of the assembly.

    Partial name binding can cause many problems, including the following:

    • The Assembly.LoadWithPartialName method might load a different assembly with the same simple name. For example, two applications might install two completely different assemblies that both have the simple name GraphicsLibrary into the global assembly cache.

    • The assembly that is actually loaded might not be backward-compatible. For example, not specifying the version might result in the loading of a much later version than the version your program was originally written to use. Changes in the later version might cause errors in your application.

    • The assembly that is actually loaded might not be forward-compatible. For example, you might have built and tested your application with the latest version of an assembly, but partial binding might load a much earlier version that lacks features your application uses.

    • Installing new applications can break existing applications. An application that uses the LoadWithPartialName method can be broken by installing a newer, incompatible version of a shared assembly.

    • Unexpected dependency loading can occur. It you load two assemblies that share a dependency, loading them with partial binding might result in one assembly using a component that it was not built or tested with.

    Because of the problems it can cause, the LoadWithPartialName method has been marked obsolete. We recommend that you use the Assembly.Load method instead, and specify full assembly display names. See Understand the Advantages and Disadvantages of Load Contexts and Consider Switching to the Default Load Context.

    If you want to use the LoadWithPartialName method because it makes assembly loading easy, consider that having your application fail with an error message that identifies the missing assembly is likely to provide a better user experience than automatically using an unknown version of the assembly, which might cause unpredictable behavior and security holes.

     Avoid Loading an Assembly into Multiple Contexts 


     

    Loading an assembly into multiple contexts can cause type identity problems. If the same type is loaded from the same assembly into two different contexts, it is as if two different types with the same name had been loaded. An InvalidCastException is thrown if you try to cast one type to the other, with the confusing message that type MyType cannot be cast to type MyType.

    For example, suppose that the ICommunicate interface is declared in an assembly named Utility, which is referenced by your program and also by other assemblies that your program loads. These other assemblies contain types that implement the ICommunicate interface, allowing your program to use them.

    Now consider what happens when your program is run. Assemblies that are referenced by your program are loaded into the default load context. If you load a target assembly by its identity, using the Load method, it will be in the default load context, and so will its dependencies. Both your program and the target assembly will use the same Utility assembly.

    However, suppose you load the target assembly by its file path, using the LoadFile method. The assembly is loaded without any context, so its dependencies are not automatically loaded. You might have a handler for the AppDomain.AssemblyResolve event to supply the dependency, and it might load the Utility assembly with no context by using the LoadFile method. Now when you create an instance of a type that is contained in the target assembly and try to assign it to a variable of type ICommunicate, an InvalidCastException is thrown because the runtime considers the ICommunicate interfaces in the two copies of the Utility assembly to be different types.

    There are many other scenarios in which an assembly can be loaded into multiple contexts. The best approach is to avoid conflicts by relocating the target assembly in your application path and using the Load method with the full display name. The assembly is then loaded into the default load context, and both assemblies use the same Utility assembly.

    If the target assembly must remain outside your application path, you can use the LoadFrom method to load it into the load-from context. If the target assembly was compiled with a reference to your application's Utility assembly, it will use the Utility assembly that your application has loaded into the default load context. Note that problems can occur if the target assembly has a dependency on a copy of the Utility assembly located outside your application path. If that assembly is loaded into the load-from context before your application loads the Utility assembly, your application's load will fail.

    The Consider Switching to the Default Load Context section discusses alternatives to using file path loads such as LoadFile and LoadFrom.

      Avoid Loading Multiple Versions of an Assembly into the Same Context  


     

    Loading multiple versions of an assembly into one load context can cause type identity problems. If the same type is loaded from two versions of the same assembly, it is as if two different types with the same name had been loaded. An InvalidCastException is thrown if you try to cast one type to the other, with the confusing message that type MyType cannot be cast to type MyType.

    For example, your program might load one version of the Utility assembly directly, and later it might load another assembly that loads a different version of the Utility assembly. Or a coding error might cause two different code paths in your application to load different versions of an assembly.

    In the default load context, this problem can occur when you use the Assembly.Load method and specify complete assembly display names that include different version numbers. For assemblies that are loaded without context, the problem can be caused by using the Assembly.LoadFile method to load the same assembly from different paths. The runtime considers two assemblies that are loaded from different paths to be different assemblies, even if their identities are the same.

    In addition to type identity problems, multiple versions of an assembly can cause a MissingMethodException if a type that is loaded from one version of the assembly is passed to code that expects that type from a different version. For example, the code might expect a method that was added to the later version.

    More subtle errors can occur if the behavior of the type changed between versions. For example, a method might throw an unexpected exception or return an unexpected value.

    Carefully review your code to ensure that only one version of an assembly is loaded. You can use the AppDomain.GetAssemblies method to determine which assemblies are loaded at any given time.

     

    Wednesday, October 23, 2013 2:58 AM