asp.net.netglobal-assembly-cache

.NET assembly is not loaded from GAC


I am banging my head against the desk for the best part of the day and cannot for the life of me understand this. An assembly that is clearly in the Global Application Cache is not found by the web app that is trying to use it. Everything I can find on the web assumes or explicitly states that there is no way to avoid loading from GAC, it's global and mandatory behaviour. And yet, in my case, it just seems to fail.

Assembly in GAC: enter image description here

Error when an .aspx page tries to use it:

System.Configuration.ConfigurationErrorsException: Could not load file or assembly 'CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral' or one of its dependencies. The system cannot find the file specified. (C:\Program Files\FMS\GeoPortal2\reporting\web.config line 34) ---> System.IO.FileNotFoundException: Could not load file or assembly 'CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral' or one of its dependencies. The system cannot find the file specified.
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)
   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.Load(String assemblyString)
   at System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)
   --- End of inner exception stack trace ---
   at System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)
   at System.Web.Configuration.AssemblyInfo.get_AssemblyInternal()
   at System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig)
   at System.Web.Compilation.BuildProvidersCompiler..ctor(VirtualPath configPath, Boolean supportLocalization, String outputAssemblyName)
   at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
   at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
   at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
   at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
   at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp)
   at System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
   at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

UPDATE: I tried to set "Copy Local" to "true" for the missing .dll so that it would be included in the project on build. Now I get a different error:

System.Web.HttpCompileException (0x80004005): c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\geo2\e2a70b87\2b9be05\App_Web_reportviewer.aspx.733fdbe7.njrhyncf.0.cs(254): error CS0433: The type 'CrystalDecisions.Web.CrystalReportViewer' exists in both 'c:\Windows\assembly\GAC_MSIL\CrystalDecisions.Web\13.0.2000.0__692fbea5521e1304\CrystalDecisions.Web.dll' and 'c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\geo2\e2a70b87\2b9be05\assembly\dl3\4e808648\047538f8_8e06d101\CrystalDecisions.Web.DLL'
   at System.Web.Compilation.AssemblyBuilder.Compile()
   at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()
   at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
   at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
   at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
   at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
   at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp)
   at System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
   at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

So the situation is that when the .dll is in the project, IIS finds both that and the GAC one, and complains about the conflict. When the assembly is not in the project, IIS can't find either. In addition, trying to open the GAC path that the error message shows (c:\Windows\assembly\GAC_MSIL\CrystalDecisions.Web) gives a "does not exist" error.

I am even more lost than I was before. What could cause such a weird behavior?


Solution

  • I can't say for sure exactly what helped, but I uninstalled and reinstalled everything CrystalReports-related and then went over everything CrystalReports-related in the .config files, tweaking anything that looked out of place. Specifically, the last thing that I fixed before it started working was a missing PublicKeyToken=692FBEA5521E1304 in the CrystalDecisions.Web assembly reference.