21

I have a web project in Visual Studio 2013, including several library projects.

Problem is that adding a reference (ie. System.Collection, System.Net) to the web project is being added as a 'Reference Assembly' from C:\Program Files (x86)\Reference Assemblies\Microsoft, when loaded in IIS it is not correctly loading the implementation of the assembly (from GAC). Example error follows.

[BadImageFormatException: Cannot load a reference assembly for execution.]

[BadImageFormatException: Could not load file or assembly 'System.Collections' or one of its dependencies. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)]
   System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
   System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +34
   System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +152
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection) +77
   System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +16
   System.Reflection.Assembly.Load(String assemblyString) +28
   System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +38

[ConfigurationErrorsException: Could not load file or assembly 'System.Collections' or one of its dependencies. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)]
   System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +728
   System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +196
   System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +45
   System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +172
   System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() +91
   System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath, Boolean& isRefAssemblyLoaded) +111
   System.Web.Compilation.BuildManager.ExecutePreAppStart() +156
   System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +624

[HttpException (0x80004005): Could not load file or assembly 'System.Collections' or one of its dependencies. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +659
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +95
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +189

Deleting the reference dlls from the bin folder fixes the issue, but I am not sure what needs changing to fix this properly.

peterdn
  • 2,386
  • 1
  • 23
  • 24
Sam
  • 5,416
  • 7
  • 47
  • 49
  • answer updated [below] – T.S. Sep 24 '15 at 18:27
  • 2
    I may actually know exactly what your problem is: You must of been checked `Copy Local = true` on your reference to `System.Collections`. And now you have it in bin and other places. your website tries to compile one in bin. So, yes answer below may just fixes it with ``. But true fix will be to set `Copy Local = false`. You generally don't want to copy local any `System.*` assemblies. – T.S. Sep 24 '15 at 18:33
  • @T.S. good idea, i've checked all the projects and none of the offending references have been set to copy local – Sam Sep 25 '15 at 08:08
  • The question remains then. How `System.Collections` gets into bin? try Building each project separately and check the output. There must be some project that copies it. – T.S. Sep 25 '15 at 13:24
  • @T.S. yes, still an issue. I think its down to targeting .net 4.6. the default assemblies in iis are 4.0 so these would be to bump the versions up (theory at this point). – Sam Sep 25 '15 at 14:05
  • Well, IIS doesn't have assemblies. You register framework with IIS and let it know how to process your code. Have you traced HOW System.Collections gets into bin? – T.S. Sep 25 '15 at 14:43
  • .NET is notorious on how it can find some assembly somewhere in your machine directory structures if it is not finding. See if you have registered frameworks on iis – T.S. Sep 25 '15 at 14:56
  • @Sam Have you resolved? – Vishal Kiri Mar 31 '16 at 12:17
  • @VishalKiri Yes, I had the 4.6 target pack installed, but not the 4.6 library installed. as such VS was generating stub dlls for the missing version. – Sam Apr 01 '16 at 16:27

6 Answers6

34

I delete the package from the /Bin folder

System.Collections and System.Collections.Concurrent

and rebuild project

its works.

Brayan Aguilar
  • 876
  • 8
  • 8
8

Resolution:

My library projects were referencing some core libs (System.* etc) with the RequiredTargetFramework option set to 3.5. This was only evident in the csproj file, example:

<Reference Include="System.Core">
  <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>

Thus causing all sorts of issues with .net versions, visual studio was trying to sort it by adding binding redirects into my web.config to point these to v4 (and include reference assemblies), unsuccessfully.

Removing all RequiredTargetFramework elements from the csproj files has solved the problem.

Sam
  • 5,416
  • 7
  • 47
  • 49
  • I would never think someone would do this for system files: Copy local, required framework, or required specific version. Unfortunately I stopped on copy local – T.S. Sep 25 '15 at 15:59
  • So, your question wasn't actually easy to solve without literally being on your computer. The possibilities were endless. We knew only so much- you were loading wrong assembly. `` stopped it wrong loading but didn't solve the issue completely. This signifies importance of giving as much info as possible – T.S. Sep 25 '15 at 16:08
  • 1
    I'm using .NET Core and had to remove the violating reference from a HintPath in the csproj file. This answer pointed me in the right direction. Thanks! – gilletty Dec 31 '16 at 13:05
4

Any time you see BadImageFormatException, you have an issue of binary format compatibility. May be your IIS pool configured to run 32-bit pool and your assemblies are built to x64, or wise versa. Or, may be, you trying to run x64 assemblies on 32 bit machine. May be you have x64 machine, anycpu-built assemblies but some 3rd party assembly is built strictly to 32-bit code.

It is one of these, or similar

Now, "usr" has good point here. You do have Cannot load a reference assembly for execution but in context with BadImageFormatException. I am wondering if this happens at compilation time. For this, try to add this to web.config

<compilation>
  <assemblies>
      <remove assembly="System.Collections" />
  . . . . 

Or, if you have

<add assembly="System.Collections. . . ."  />

Try removing it first

Now, it is normal that GAC is preferred location for reference unless you supply probing settings

T.S.
  • 18,195
  • 11
  • 58
  • 78
  • Also consider that the app pool may be serving several sites, and it may be one of those other sites that has the mismatched bitness loaded. – StingyJack Sep 24 '15 at 17:15
  • 1
    The error message is `Cannot load a reference assembly for execution` which points away from bitness mismatches. – usr Sep 24 '15 at 17:20
  • @usr Thaks for pointing this out. I updated the answer. It could be that, or could be something before that. And also see my comment to the question – T.S. Sep 24 '15 at 18:36
  • @T.S. Thanks! removing the assemblies that were giving the error fixed the issue – Sam Sep 25 '15 at 08:26
3

It happened to me after VS 15.8 update. Setting "Copy Local" to false solved the issue for each assembly that gave me the error. In addition I removed (by hand) duplicated "<Private>" tags in .csproj.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
2

This issue will often happen if your binding redirects refer to earlier versions than what your references depend on, and this may happen after updating packages (e.g., through NuGet). To resolve generally, I've added a series of steps as an answer here. However, for this particular issue, I recommend specifically following step 5 which is:

Remove all the assembly bindings from all app.config and Web.config files then build your solution. app.config bindings are not required anymore. Web.config bindings will be re-added in the next step, but removing them first ensures you don't have any outdated versions in your bindings.

Neo
  • 4,145
  • 6
  • 53
  • 76
0

In my case, I added the nuget package System.Collections to my asp.net 4.6.1 project and, for some reason, it wasn't referenced into the csproj file. I manually edited the csproj file and added the reference. Reloaded it, and, voila, worked!

Marco Alves
  • 2,776
  • 3
  • 23
  • 33