We have an Asp.Net MVC project that we have recently upgraded from .Net 4.6.1 to .Net 4.8. It has some dependencies on other projects in our solution that have also been upgraded. The MVC project itself uses System.IO.Compression to zip some files as does one of the other projects it depends on.
Since upgrading, we are seeing some strange behaviour with System.IO.Compression. If we build the new solution, it doesn't automatically copy System.IO.Compression.dll and System.IO.Compression.FileSystem.dll to the output bin folder. This causes a runtime exception on the lines of code that tries to do zipping…
System.IO.FileNotFoundException: 'Could not load file or assembly 'System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.'
This is unsurprising I suppose if the dll is not even copied to the bin folder.
If I set the "Copy Local" property to true on the System.IO.Compression.dll and System.IO.Compression.FileSystem.dll in the references of the MVC project, the files are copied from
"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.8" to the bin folder, but the following error is shown in the browser when the application first starts…
[BadImageFormatException: Cannot load a reference assembly for execution.]
[BadImageFormatException: Could not load file or assembly 'System.IO.Compression' 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.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +232
System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection) +113
System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +23
System.Reflection.Assembly.Load(String assemblyString) +35
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +48
[ConfigurationErrorsException: Could not load file or assembly 'System.IO.Compression' 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) +767
System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +256
System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +58
System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +287
System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() +69
System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath, Boolean& isRefAssemblyLoaded) +137
System.Web.Compilation.BuildManager.ExecutePreAppStart() +172
System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +854
[HttpException (0x80004005): Could not load file or assembly 'System.IO.Compression' 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) +532
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +111
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +724
Curiously, the previous .Net 4.6.1 version that worked, which had Nuget references to System.IO.Compression, copied the files from
"C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib" into the bin folder. If we manually copy these versions of the files into our .Net 4.8 bin folder, the application works without any exceptions.
I have tried various combinations of bindingRedirects in the web.config file, but without success.
I have been reading other StackOverflow questions that seem related, but haven't been able to a) fully understand the issue and b) know how to fix it so that we can successfully run the .Net 4.8 version and zip files.
Any help would be greatly appreciated
@Charlieface has correctly identified that with .Net 4.8 there is no need to reference any Nuget packages in order to use System.IO.Compression and System.IO.Compression.FileSystem to zip files. To make this work, I uninstalled all Nuget references in the solution for System.IO.Compression and System.IO.Compression.ZipFile. Once the Nuget references had been uninstalled, I ensured that the relevant projects had direct Assembly references to System.IO.Compression and System.IO.Compression.FileSystem (i.e. right-click "Add Reference…" or "Add Assembly Reference…")
I also had to remove any entries for System.IO.Compression.* files from app.confg and web.config files. These app.config and web.config entries had bindingRedirects on that were also causing the issue.
What I have noticed with this issue, is that NuGet, when updating System.IO.Compression to the version 4.3.0, is updating the web.config
to the version 4.2.0.
If I manually edit the web.config, to point the new version from 4.2.0 to 4.3.0 and old version to 4.1.0, everything works.
Please refer to the attached screenshots as reference. Hope this works as it did to me.
NuGet: System.IO.Compression:
Web.Config as NuGet updated:
Web.Config manually updated:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With