无法加载文件或程序集“System.Security.Cryptography.Algorithms,版本 = 4.1.0.0

Could not load file or assembly 'System.Security.Cryptography.Algorithms, Version = 4.1.0.0

我正在尝试在我的 .NET Standard 1.4 库中使用 System.Security.Cryptography.RNGCryptoServiceProvider class,根据 this 主题,我的代码如下所示:

    private byte[] GenerateRandomNumber(int length)
    {
        using (var randomNumberGenerator = RandomNumberGenerator.Create())
        {
            var number = new byte[length];
            randomNumberGenerator.GetBytes(number);

            return number;
        }
    }

我还安装了 NuGet 库:

但是尝试启动它给了我:

'Could not load file or package' System.Security.Cryptography.Algorithms, Version = 4.1.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a 'or one of its dependencies. The specified file could not be found. '

NuGet page there is no 4.1.0.0 version, only 4.1.0-rc2-24027 上安装此版本后我得到完全相同的异常。

怎么了?

编辑: 从 .NET Standard 1.4 切换到 1.6 没有帮助

编辑2:

当我在 RandomNumberGenerator 上按 F12 时:

#region Assembly System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Users\x.y\.nuget\packages\system.security.cryptography.algorithms.3.0\ref\netstandard1.4\System.Security.Cryptography.Algorithms.dll
#endregion

namespace System.Security.Cryptography
{
    public abstract class RandomNumberGenerator : IDisposable
    {
        protected RandomNumberGenerator();

        public static RandomNumberGenerator Create();
        public void Dispose();
        public abstract void GetBytes(byte[] data);
        protected virtual void Dispose(bool disposing);
    }
}

因此它需要 4.1.0 版本(NuGet 上不存在)但路径设置为 4.3.0

除了拥有 .NET Standard 库之外,您还拥有一个应用程序(如控制台应用程序)或一个测试项目。应用程序的平台决定了要加载的 .NET Standard 库引用的特定程序集。

因此您的库引用了 System.Security.Cryptography.Algorithms 4.3.0,但是为您的平台加载的程序集的实际版本可能是 4.1.0(即您在 .NET Framework 4.6.1 上获得的版本)。

因此您需要通知您的应用程序将所需版本 (4.3.0) 重定向到您运行时的实际版本 (4.1.0)。您可以在 app.config 文件中执行此操作。请记住,此文件由应用程序而不是库使用。将 app.config 文件添加到您的库不会有什么不同。

我尝试创建一个像您描述的那样的小项目,除了引用 System.Security.Cryptography.Algorithms 4.3.0 的 .NET Standard 1.4 库外,还有一个 NET Framework 4.62 控制台应用程序,我必须包括一个app.config 包含以下内容的文件才能正常工作:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
  </startup>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.1.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

有趣的是,如果您切换到 .NET Standard 2.0,这似乎不是什么问题。

我找到的解决方案:

  • 将库从 .NET Standard 1.4 更新到 2.0 然后它可以用于:

  • System.Security.Cryptography.Algorithms v=4.3.0

  • System.Security.Cryptography.Primitives v=4.3.0

  • 根据 this 主题,它应该适用于 .NET Standard 1.3 和:

  • System.Security.Cryptography.Algorithms v=4.2.0

  • System.Security.Cryptography.Primitives v=4.0.0

Martin Liversage 提出的 .Net Standard 1.4 解决方案是不错的选择。

如果要在 "classic" 项目中使用此库,您可能需要在使用项目/库中激活自动绑定重定向生成(单元测试项目在这里算作库)。这可以通过将这些添加到消费(!)项目的 csproj 文件的属性来完成:

<PropertyGroup>
  <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
  <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

有关更多详细信息和选项,请参阅相关的 "Issues with .NET Standard 2.0 with .NET Framework & NuGet" announcement post

在我的例子中,我也只是将 NuGet 包添加到主 Net 应用程序中(尽管我在单独的 NetStandard 2.0 class lib 中使用加密的东西,不是 在主应用程序代码库中)并解决了问题。

此外,我的主要网络应用程序是 Net.Framework 4.6.1