title: Binding redirect when importing AngleSharp in .Net 4.7.2 somehow tries to pull in NetStandard 2 as a dll
body: <p>I have a legacy app running on an old Windows 2008 R2 server. The app has gone through many .Net versions, and is currently on 4.7.2. It has been stable as a rock for years, and while there are migration plans to move away from the old physical server, it has to live for a while longer.</p>
  
  <p>A new feature sees the need for some HTML scraping. I added the NuGet package for AngleSharp v0.12.0, unit tested and all was well on my Win10 dev machine. The new class that used AngleSharp simply worked.</p>
  
  <p>So I deployed to the prod server, including the changes to app.config;</p>
  
  <pre><code>  &lt;runtime&gt;
      &lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&gt;
        &lt;dependentAssembly&gt;
          &lt;assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /&gt;
          &lt;bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" /&gt;
        &lt;/dependentAssembly&gt;
        &lt;dependentAssembly&gt;
          &lt;assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /&gt;
          &lt;bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" /&gt;
        &lt;/dependentAssembly&gt;
      &lt;/assemblyBinding&gt;
    &lt;/runtime&gt;
  </code></pre>
  
  <p>These are the only changes I could identify from the older version.</p>
  
  <p>When I run the app in production, it crashes. </p>
  
  <pre><code>System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
  </code></pre>
  
  <p>After doing a bit of searching online, I saw someone point out a similar problem (.Net Core however, but still similar), and they pointed out that trying to call <code>Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);</code> might make a difference. Reference:
  <a href="https://github.com/DiscUtils/DiscUtils/issues/77" rel="nofollow noreferrer">https://github.com/DiscUtils/DiscUtils/issues/77</a></p>
  
  <p>It didn't for me, but now I got more funky messages:</p>
  
  <pre><code>System.IO.FileNotFoundException: Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
  </code></pre>
  
  <p>How did netstandard get into this? I don't know. I also see this in the binding log that I get thanks to Splats exception logging:</p>
  
  <pre><code>5496 === Pre-bind state information ===
  5497 LOG: DisplayName = netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
  5498  (Fully-specified)
  5499 LOG: Appbase = file:///E:/dcollect/Ingest/
  5500 LOG: Initial PrivatePath = NULL
  5501 Calling assembly : System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
  5502 ===
  5503 LOG: This bind starts in default load context.
  5504 LOG: Using application configuration file: E:\dcollect\Ingest\Ingest.exe.Config
  5505 LOG: Using host configuration file:
  5506 LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
  5507 LOG: Post-policy reference: netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
  5508 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard.DLL.
  5509 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard/netstandard.DLL.
  5510 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard.EXE.
  5511 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/netstandard/netstandard.EXE.
  </code></pre>
  
  <p>I have no known (to me) references to Netstandard in my project, all the projects are .Net Framework 4.5, 4.6.x or 4.7.x projects.</p>
  
  <p>I also came across this one that seems like it might be related:
  <code>https://github.com/dotnet/announcements/issues/31</code></p>
  
  <p>I tried converting my project to a PackageReference project, but that also did not change anything.</p>
  
  <p>For completeness, here is the binding log for my initial attempt at using AngleSharp.</p>
  
  <pre><code>5576 [20:24:01.522] &lt;ERROR&gt; EventParser: Exception caught: System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
  5577 File name: 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
  5578    at AngleSharp.Browser.EncodingMetaHandler..ctor()
  5579    at AngleSharp.Configuration..ctor(IEnumerable`1 services)
  5580    at AngleSharp.Configuration.get_Default()
  5581    at Teller.Charts.DataCollection.EventParser.ParseHTML(String html)
  5582 === Pre-bind state information ===
  5583 LOG: DisplayName = System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  5584  (Fully-specified)
  5585 LOG: Appbase = file:///E:/dcollect/Ingest/
  5586 LOG: Initial PrivatePath = NULL
  5587 Calling assembly : AngleSharp, Version=0.11.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea.
  5588 ===
  5589 LOG: This bind starts in default load context.
  5590 LOG: Using application configuration file: E:\dcollect\Ingest\Ingest.exe.Config
  5591 LOG: Using host configuration file:
  5592 LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
  5593 LOG: Post-policy reference: System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
  5594 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/System.Text.Encoding.CodePages.DLL.
  5595 WRN: Comparing the assembly name resulted in the mismatch: Minor Version
  5596 ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
  </code></pre>
  
  <p>I am sure there must be some simple redirect magic I am missing here. Is it possible to convince my project to load this for Net Framework v4.7.2 and just work? </p>
  
  <p>Thanks for any suggestions!</p>
  
  <p><strong>EDIT MAY 14th</strong>:
  The point of peak confusion for me is all the different version numbers involved. </p>
  
  <p>The AngleSharp 0.12.0 NuGet package depends on System.Text.Encoding.CodePages >= 4.5.0. </p>
  
  <p>So it automatically installed v4.5.0 even if v4.5.1 exists because lowest dependency behavior.</p>
  
  <p>If I right-click the actual DLL that gets put into my bin\Debug folder, choose Properties and then Version, it reports File and product version 4.6.26515.</p>
  
  <p>But in my app.config, the binding redirect I get refers to 4.1.1.0.</p>
  
  <pre><code>    &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" /&gt;
      &lt;/dependentAssembly&gt;
  </code></pre>
  
  <p>(I tried replacing both instances of 4.1.1.0 with 4.6.26515.0 just for fun but that changed nothing)</p>
  
  <p>And then, as stated above, the log claims:</p>
  
  <pre><code>29014 [22:42:44.735] &lt;ERROR&gt; EventInfoCreator: Failed to parse: System.IO.FileLoadException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
  29015 File name: 'System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
  29016    at AngleSharp.Browser.EncodingMetaHandler..ctor()
  29017    at AngleSharp.Configuration..ctor(IEnumerable`1 services)
  29018    at AngleSharp.BrowsingContext.New(IConfiguration configuration)
  29019    at Teller.Charts.DataCollection.EventParser.ParseHTML(String html)
  29020    at Teller.Charts.DataCollection.EventParser.ParseFile(String filePath)
  29021    at Teller.Charts.DataCollection.EventInfoCreator.CreateEventInfoProps(String html, String storageDirectory)
  </code></pre>
  
  <p>So there is obviously some version mismatch here, but I frankly have no idea which of these version numbers are important. </p>
  
  <pre><code>29034 LOG: Attempting download of new URL file:///E:/dcollect/Ingest/System.Text.Encoding.CodePages.DLL.
  29035 WRN: Comparing the assembly name resulted in the mismatch: Minor Version
  </code></pre>
  
  <p>This seems to indicate that it is unhappy with the minor version, but... which one?</p>
  
  <p>4.0.2.0 that AngleSharp seems to ask for?
  4.1.1.0 that the app.config refers to?
  4.6.26515.0 that is the version the dll actually claims to be?</p>