Fehlermeldung über fehlende Assemblies nach Umstellen einer Webanwendung von .NET 4.6 nach .NET 4.7.2

Nachdem ich eine ASP.NET-Webanwendung (MVC und WebForms) von .NET 4.6.2 nach .NET 4.7.2 umgestellt hatte, hagelte es Fehlermeldungen dieser Form:

Die Datei oder Assembly „System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a“ oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.

Oder auch:

Die Datei oder Assembly „System.Runtime.InteropServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a“ oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.

Lösung

Ich bin dann wie folgt zur Lösung vorgegangen:

  1. Alle NuGet-Pakete via Package Manager Console Update-Package -Reinstall aktualisieren lassen.

  2. In der Datei „Web.config“ diese Zeile unter <configuration><system.web>
    <compilation><assemblies> ergänzt:

    <add assembly="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
    
  3. In der Datei „Web.config“ alle Einträge unter <configuration><runtime><assemblyBinding> entfernt.

  4. Alle Dateien im „Bin“-Ordner der Webanwendung löschen.

  5. Einen Rebuild der Solution gemacht.

  6. Die unter „Error List“ als Warnungen ausgegebenen fehlenden Binding-Redirects per Doppelklick wieder ergänzen lassen.

Anschließend lief die Webanwendung wieder.

Das hat sowohl bei einer MVC-Anwendung, als auch bei einer WebForms-Anwendung funktioniert.

Wie aus dem Nichts habe ich jetzt bei einer, wie oben beschrieben, angepassten Anwendung folgende Meldung beim Aufruf erhalten:

[BadImageFormatException: Es kann keine Verweisassembly für die Ausführung geladen werden.]

[BadImageFormatException: Die Datei oder Assembly „System.Net.Http“ oder eine Abhängigkeit davon wurde nicht gefunden. Verweisassemblys sollten nicht für die Ausführung geladen werden. Sie können nur in einem Ladekontext nur für die Reflektion geladen werden. (Ausnahme von 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) +36
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) +21
System.Reflection.Assembly.Load(String assemblyString) +28
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +38

[ConfigurationErrorsException: Die Datei oder Assembly „System.Net.Http“ oder eine Abhängigkeit davon wurde nicht gefunden. Verweisassemblys sollten nicht für die Ausführung geladen werden. Sie können nur in einem Ladekontext nur für die Reflektion geladen werden. (Ausnahme von HRESULT: 0x80131058)]
System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +726
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) +695

[HttpException (0x80004005): Die Datei oder Assembly „System.Net.Http“ oder eine Abhängigkeit davon wurde nicht gefunden. Verweisassemblys sollten nicht für die Ausführung geladen werden. Sie können nur in einem Ladekontext nur für die Reflektion geladen werden. (Ausnahme von HRESULT: 0x80131058)]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +659
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +89
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +188

Auf Englisch heißen die wichtigsten Meldungen:

Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context.

Ich bin erst mal noch ratlos, was da nun wieder die Ursache ist.

Diese Frage/Antwort empfiehlt, den „Bin“-Ordner im Web-Projekt zu löschen.

Update:

Das Löschen des „Bin“-Ordners hat doch geholfen, ich habe es in der ursprünglichen Liste oben ergänzt.

Manchmal muss man auch folgende Schritte bei einer bereits funktionierenden Anwendung mit .NET 4.7.2 machen:

  1. In der Datei „Web.config“ alle Einträge unterhalb von <configuration><runtime><assemblyBinding> entfernen.

  2. Alle Dateien im “Bin”-Ordner der Webanwendung löschen.

  3. Einen Rebuild der Solution machen.

  4. Die unter “Error List” als Warnungen ausgegebenen fehlenden Binding-Redirects per Doppelklick wieder in der „Web.config“ ergänzen lassen.

Das war bei mir erforderlich, als ich einige NuGet-Pakete aktualisiert hatte.

Die Fehlermeldung kann auch lauten:

CS0012: The type ‚ValueType‘ is defined in an assembly that is not referenced. You must add a reference to assembly ‚netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51‘.

Die Fehlermeldung kann weiterhin auch lauten:

Die Datei oder Assembly „System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51“ oder eine Abhängigkeit davon wurde nicht gefunden. Die gefundene Manifestdefinition der Assembly stimmt nicht mit dem Assemblyverweis überein. (Ausnahme von HRESULT: 0x80131040)

Manchmal reicht auch schon dieses Vorgehen aus:

Also einfach alle Pakete neu installieren lassen.

Chat GPT hat noch folgendes vorgeschlagen:

Kurzfassung vorweg: Wenn es nur lokal mit IIS Express kracht, ist fast immer die lokale Host‑Konfiguration, Bitness (x86/x64), ein Cache oder eine „falsche“ Kopie von System.Net.Http.dll schuld – nicht dein Code.

Hier sind bewusst die ungewöhnlicheren/„absurderen“ Ursachen inkl. schneller Checks & Fixes.


Ungewöhnliche Ursachen & schnelle Checks

1) IIS Express läuft 32‑bit, dein Binding/Framework ist aber 64‑bit

  • Symptom: In Prod (IIS 64‑bit) ok, lokal Fehler.

  • Check: VS → Tools → Options → Projects and Solutions → IIS Express → „Use the 64‑bit version of IIS Express“ aktivieren.
    Alternativ prüfen, welcher Prozess startet: iisexpress.exe aus Program Files (x86) = 32‑bit.

  • Fix: Auf 64‑bit umstellen, VS neu starten.


2) .vs\config\applicationhost.config zeigt (noch) auf den falschen Ordner

  • Warum absurd: VS behält alte Pfade, wenn du Ordner/Solution verschoben hast. Dann nutzt IIS Express ein anderes web.config ohne deine Redirects.

  • Check: Datei öffnen: .vs\<SolutionName>\config\applicationhost.config → Suche nach deinem
    <virtualDirectory physicalPath="..."> muss exakt auf dein Projektwurzelverzeichnis zeigen.

  • Fix: Pfad korrigieren oder den kompletten .vs‑Ordner löschen (VS generiert ihn neu).


3) Temporäre ASP.NET‑Caches liefern eine veraltete/kaputte DLL

  • Check/Fix:

    1. VS schließen, IIS Express beenden.

    2. Löschen:

      • bin + obj deines Web‑Projekts

      • %LOCALAPPDATA%\Temp\Temporary ASP.NET Files\

      • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\

      • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\

    3. VS neu starten, Rebuild, dann starten.


4) Eine falsche Kopie von System.Net.Http.dll im bin überschreibt die aus dem Framework

  • Wie passiert das? Alte NuGet‑Pakete (Microsoft.Net.Http o. ä.) legen ihre eigene System.Net.Http.dll ab (teils sogar .NET 4.0‑Build).

  • Check: Liegt bin\System.Net.Http.dll? Datei‑Eigenschaften → Produkt/Dateiversion vs. AssemblyVersion.

  • Fix: DLL im bin entfernen; im Projekt: Referenz auf das NuGet‑Paket System.Net.Http für .NET‑Framework entfernen (seit 4.7+ ist es Teil des Frameworks). „Copy Local“ für System.Net.Http auf False.


5) Binding‑Redirect im falschen Namespace – damit wirkt er nicht

  • Symptom: Du hast einen Redirect, aber CLR ignoriert ihn.

  • Check: In web.config muss der Knoten so aussehen:

    xml
    

    KopierenBearbeiten

    <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>

    Fehlt das xmlns, ist der ganze Block wirkungslos.

  • Fix: Namespace ergänzen, Neustart.


6) Ein globales Binding‑Redirect zwingt lokal auf 4.0.0.0

  • Wo kann das stecken?

    • C:\Windows\Microsoft.NET\Framework*\v4.0.30319\Config\machine.config

    • %USERPROFILE%\Documents\IISExpress\config\applicationhost.config

    • .vs\...\applicationhost.config

  • Check: In diesen Dateien nach System.Net.Http suchen.

  • Fix: Falsche Redirects entfernen/anpassen. (Zuverlässig: .vs löschen → neu erzeugen lassen.)


7) Bitness‑spezifische GAC: x86‑GAC hat nicht, was x64‑GAC hat (oder umgekehrt)

  • Symptom: Nur bei 32‑bit‑Host (IIS Express x86) schlägt Laden fehl.

  • Check: Existiert System.Net.Http unter

    • C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Net.Http\ (AnyCPU) und

    • ...\GAC_32\... / ...\GAC_64\...?

  • Fix: Auf 64‑bit hosten oder fehlende .NET‑Framework‑Komponenten/Windows‑Update reparieren.


8) DEVPATH/Umgebungsvariablen oder eigener AssemblyResolve‑Handler funken dazwischen

  • Warum absurd: Selten setzt ein Tool (Build‑Script, Test‑Runner) DEVPATH oder ihr habt einen globalen AppDomain.AssemblyResolve.

  • Check: In einer „Developer Command Prompt“ set DEVPATH → darf leer sein.

  • Fix: Variable entfernen; ggf. temporär AssemblyResolve auskommentieren um zu testen.


9) NuGet‑Cache liefert eine überholte Fassung

  • Fix:

    • VS → Tools → NuGet Package Manager → Package Manager Settings → GeneralClear All NuGet Caches

    • oder CLI: nuget locals all -clear
      Danach bin/obj löschen und neu bauen.


10) Debug‑Start nutzt nicht deine reale web.config

  • Wie kommt’s? Selten sind Build‑/Transform‑Tools (z. B. SlowCheetah) so konfiguriert, dass zur Debug‑Zeit eine transformierte Datei verwendet wird – oder dein IIS‑Express‑„Site Root“ liegt eine Ebene höher und greift eine andere web.config.

  • Check: In Ausgabe-Fenster beim Start den physikalischen Pfad und die geladenen Configs ansehen; vgl. mit Punkt 2.

  • Fix: Transform nur beim Publish, nicht beim F5; Site Root korrigieren.


11) Security/AV blockiert genau diese DLL im Projektordner

  • Symptom: In Prod (Server) ok, lokal blockiert „Controlled Folder Access“/EDR.

  • Check: Windows‑Sicherheitsverlauf/AV‑Logs; NTFS‑Rechte des Projektordners.

  • Fix: Lösungspfad whitelisten oder unter eigenem dev‑Pfad arbeiten.


12) Pfadprobleme (UNC, sehr lange Pfade, Sonderzeichen)

  • Effekt: Dateien werden nicht zuverlässig kopiert/geladen; Loader meldet „nicht gefunden“.

  • Fix: Projekt auf kurzen lokalen Pfad ohne Sonderzeichen legen (z. B. C:\src\...).


Der schnellste Diagnoseweg (lohnt sich wirklich)

Nutze den Assembly Binding Log Viewer (Fuslogvw) – der sagt dir genau, welche Version wo gesucht und warum nicht gefunden wurde.

  1. VS als Admin starten.

  2. fuslogvw.exe öffnen (Developer Command Prompt → „Developer Command Prompt for VS“).

  3. Settings: „Log bind failures“ + „Enable custom log path“ (Ordner vorher anlegen, z. B. C:\fuslog).

  4. Logs leeren, App mit IIS Express starten, Seite aufrufen → in Fuslog erscheint ein Eintrag für System.Net.Http.

  5. Im Log siehst du: angeforderte Version, angewandte Redirects, Suchpfade (bin, GAC_32/64, …). Das zeigt dir meist sofort die Ursache (falscher Root, Bitness, falsches Redirect, DLL im bin, etc.).


Mini‑Checkliste „10‑Minuten‑Reset“

  1. VS schließen, IIS Express beenden.

  2. bin/obj, Temporary ASP.NET Files, NuGet‑Caches löschen.

  3. .vs‑Ordner der Solution löschen (regeneriert applicationhost.config).

  4. In VS 64‑bit IIS Express aktivieren.

  5. Sicherstellen, dass keine System.Net.Http.dll im bin landet.

  6. web.config‑Redirect (inkl. xmlns) auf 4.2.0.0 setzen.

  7. Nochmal starten; wenn’s noch scheitert → Fuslog anwerfen.

Aktuell habe ich in einer Legacy-WebForms-Anwendung in .NET Framework 4.8 folgende Fehlermeldung:

Die Datei oder Assembly „System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a“ oder eine Abhängigkeit davon wurde nicht gefunden. Das System kann die angegebene Datei nicht finden.

Auch dort hat es geholfen, die <assemblyBinding>-Inhalte in der „Web.config“ zu entfernen und neu ergänzen zu lassen, so wie hier weiter oben beschrieben.