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

15

我想在我的.NET Standard 1.4库中使用System.Security.Cryptography.RNGCryptoServiceProvider类,根据这个话题,我的代码看起来像这样:

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

            return number;
        }
    }

我还从NuGet安装了以下库:

  • System.Security.Cryptography.Algorithms v=4.3.0
  • System.Security.Cryptography.Primitives v=4.3.0

但是尝试启动它会给我以下错误信息:

'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页上没有4.1.0.0版本,只有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\4.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 1.4有以下依赖项,你也添加了这些引用吗?System.IO (>= 4.3.0)System.Runtime (>= 4.3.0)System.Security.Cryptography.Primitives (>= 4.3.0) - Equalsk
是的,我有System.IO 4.3.0、System.Runtime 4.3.0和System.Security.Cryptography.Primitives 4.3.0。 - Carlos28
我建议您使用Fusion Log Viewer获取有关加载错误的详细信息。很可能您bin文件夹中的程序集版本与请求的版本不同,即使它们是兼容的。然后,您需要在app.config中添加一个绑定重定向,将所需版本重定向到实际版本。 - Martin Liversage
融合日志查看器没有显示任何有关它的数据(也许是因为程序抛出了System.IO.FileNotFoundException?)如果涉及绑定重定向,我目前正在从单元测试运行此代码,所以我相信它在那里不起作用。 - Carlos28
1
@Carlos28:我可以确认,当使用.NET Core/Standard时,融合日志查看器似乎并不总是报告程序集绑定。我不知道这是一个错误还是一个等待实现的功能。然而,融合日志确实非常有用,所以我希望我们将来能够继续使用它。 - Martin Liversage
你在哪种项目中使用这个库?是.NET Core控制台应用程序,经典的ASP.NET Web应用程序,经典测试项目,.NET Core测试项目等等? - Martin Ullrich
4个回答

16

除了拥有一个.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文件添加到您的库中不会产生任何影响。

我尝试创建了一个类似于您描述的小项目,除了一个.NET Standard 1.4库引用了System.Security.Cryptography.Algorithms 4.3.0之外,还有一个.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,则似乎这个问题会减少。


1
@Carlos28:要解决你的问题,你需要确保 System.Security.Cryptography.Algorithms.dll 存在于你的 bin 文件夹中。如果它的程序集版本与 4.3.0 不同,你需要创建一个绑定重定向来将 4.3.0 重定向到你的 bin 文件夹中的版本。你可能需要使用不同于我在答案中提供的重定向。这取决于你的应用程序平台。 - Martin Liversage

9

如果要在“传统”项目中使用此库,则可能需要在消费项目/库(单元测试项目在此处计数)中启用自动生成绑定重定向。可以通过向消费方(!) 项目的csproj文件添加以下属性来实现:

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

更多详细信息和选项,请参见相关的“关于.NET Standard 2.0与.NET Framework&NuGet存在的问题”公告帖


那对我有用(Net 4.8 引用 Net Std 2.0)。我还在同一属性组中添加了 <RestoreProjectStyle>PackageReference</RestoreProjectStyle>。 - Anton Krouglov

0
我找到的解决方案:
  • 将库从.NET Standard 1.4升级到2.0,然后它可以与以下版本一起使用:

  • System.Security.Cryptography.Algorithms v=4.3.0

  • System.Security.Cryptography.Primitives v=4.3.0

根据这个话题,它应该可以在.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 解决方案是一个不错的选择。


0
在我的情况下,我只是将NuGet包添加到主Net应用程序中(尽管我在单独的NetStandard 2.0类库中使用加密功能,而不是在主应用程序代码库中),这解决了问题。
此外,我的主要Net应用程序是Net.Framework 4.6.1。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接