HtmlSanitizer icon indicating copy to clipboard operation
HtmlSanitizer copied to clipboard

AngleSharp dependency issue in .NET Framework (IIS-hosted WCF service)

Open qwerty-debug opened this issue 1 year ago • 5 comments

I installed HtmlSaniziter 8.0.865 (+ dependencies) from NuGet. Running my project locally in debug mode works fine, but when publishing to a server I run into the following issue:

System.TypeInitializationException: The type initializer for 'Ganss.Xss.HtmlSanitizer' threw an exception. ---> System.IO.FileLoadException: Could not load file or assembly 'AngleSharp, Version=0.17.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) at Ganss.Xss.HtmlSanitizer..cctor() --- End of inner exception stack trace ---

note:

  • The issue is similar to https://github.com/mganss/HtmlSanitizer/issues/528 , except that the problem is not resolved by clearing build folders.
  • The issue only occurs in published code (IIS), not in debug mode.
  • The issue does not occur in .NET 7 / 8 (different project).

After some experimenting I found a workaround: if I download HtmlSanitizer 8.0.865, AngleSharp 0.17.1 and AngleSharp.Css 0.17.0 from GitHub and then build from source everything works.

qwerty-debug avatar Apr 29 '24 07:04 qwerty-debug

Have you checked for https://github.com/mganss/HtmlSanitizer/issues/528#issuecomment-1939621500?

mganss avatar Apr 29 '24 13:04 mganss

Yes. As mentioned above I tried your suggestion from https://github.com/mganss/HtmlSanitizer/issues/528 , but it didn't work.

qwerty-debug avatar Apr 29 '24 15:04 qwerty-debug

I meant the binding redirect fix that worked for @Chmielinski.

mganss avatar Apr 29 '24 15:04 mganss

Not sure I follow...

@Chmielinski mentions the issue being caused by an out-of-date binding redirect for AngleSharp. I assume he simply removed the binding redirect and cleared his build folders to fix the issue.

My project does not have any binding redirect, and until last week I had no dependency on HtmlSanitizer, AngleSharp or AngleSharp.Css.

qwerty-debug avatar Apr 29 '24 15:04 qwerty-debug

Perhaps you can try Fuslogvw to debug the issue.

mganss avatar Apr 29 '24 16:04 mganss

I think you'll need a binding redirect. AngleSharp.Css 0.17.0 references AngleSharp 0.17.0 while the latest HtmlSanitizer references AngleSharp 0.17.1. In .NET Framework 4.5.1 and later binding redirects should be created automatically.

See https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versions and https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/how-to-enable-and-disable-automatic-binding-redirection#enable-automatic-binding-redirects-in-web-apps

When you create a net48 desktop application, the following gets automatically added to the App.config when adding the HtmlSanitizer NuGet package:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="AngleSharp" publicKeyToken="e83494dcdc6d31ea" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-0.17.1.0" newVersion="0.17.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

mganss avatar May 02 '24 18:05 mganss

Looks like App.config of the WCF service project does indeed have an (automatically added) binding redirect for AngleSharp, but the Web.config of the website hosting the WCF service does not.

Copying over the binding redirect from App.config to Web.config solves the issue.

Thanks for your time.

qwerty-debug avatar May 02 '24 21:05 qwerty-debug

We have the same problem when using the HtmlSanitizer library which references the AngleSharp 0.17.1 and AngleSharp.Css 0.17.0 libraries. However, the AngleSharp.Css 0.17.0 library subsequently references the AngleSharp 0.17.0 library, which is absent in the application directory. The application directory contains the AngleSharp version 0.17.1 library instead.

Binding redirects in the .config file cannot be used, as HtmlSanitizer is not used in a standalone application, but as part of a DevOps Pipeline process with dynamically created types at multiple levels using reflection. The chain of references is as follows:

Microsoft DevOps Server Release Pipeline >

  > Pipeline Task A (PowerShell) New-Object B.dll.BClass.BMethod() >
    (1. reflection from PowerShell -> .NET Framework and dynamic type load)

    > B.dll.BClass.BMethod (.NET Framework) Assembly.LoadFrom(C.dll).CreateInstance(CClass).GetMethod(CMethod).Invoke() >
      (2. reflection from .NET Framework -> .NET Framework and dynamic type load)

      > C.dll.CClass.CMethod (.NET Framework) Assembly.LoadFrom(D.dll).CreateInstance(DClass).GetMethod(DMethod).Invoke() >
        (3. reflection from .NET Framework -> .NET Framework and dynamic type load)

        > D.dll.DClass.DMethod (.NET Framework)
---> HtmlSanitizer => FileNotFoundException [Could not load file or assembly 'AngleSharp, Version=0.17.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea' or one of its dependencies. The system cannot find the file specified.]
          D.dll -> references HtmlSanitizer 8.0.865 -> references !!!AngleSharp 0.17.1 AND AngleSharp.Css 0.17.0 -> references !!!AngleSharp 0.17.0

tibx avatar May 30 '24 15:05 tibx