无法加载文件或程序集“System.ComponentModel.Annotations,版本=4.1.0.0

Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.1.0.0

我有一个 .NET Standard 1.4 class 库引用了 System.ComponentModel.Annotations (4.3.0) NuGet 包。

然后我从 .NET Framework 4.6.2 测试项目中引用这个 class 库。它构建良好,但在运行时出现以下错误:

System.IO.FileLoadException occurred HResult=0x80131040
Message=Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.1.0.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)

我尝试从 net462 项目添加对 System.ComponentModel.Annotations (4.3.0) NuGet 包的引用,但这没有任何区别。

我尝试从 net462 项目添加对 .NET Standard 库的引用,但仍然没有成功。

我是不是漏掉了什么?这是已知错误吗?如果是,是否有解决方法?

非常感谢任何帮助!

在很多情况下,这可以通过在您的测试项目的csproj 文件中添加以下代码来解决:

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

这会强制构建过程在输出目录中创建一个包含所需绑定重定向的 .dll.config 文件。

原因是“经典”csproj 测试项目是真正的“库”,默认情况下不需要绑定重定向。但是 运行 单元测试需要这个。如果引用的项目需要这些重定向才能正常工作,这只会成为一个问题。这通常在直接安装引用库使用的所有 NuGet 包时有效,但使用新的 PackageReference 样式的 NuGet 包时,它不会。

查看此修复有帮助的其他实例:

在我的例子中,我使用的是 4.0.0,所以我通过添加

来修复它
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity name="System.ComponentModel.Annotations"
                      publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="4.1.0.0" newVersion="4.0.0.0"/>
  </dependentAssembly>

适配您需要的版本。

我遇到了类似的问题,但上述答案中的 none 对我有所帮助。事实证明,解决方案非常简单,我只是 运行 在包管理器中执行以下命令:

安装包 System.ComponentModel.Annotations - 版本 4.1.0

对我来说,none 的其他解决方案有效。

我通过自己手动添加对 System.ComponentModel.DataAnnotations 的引用(通过项目 -> 引用)解决了这个问题,而不是让 Visual Studio 通过灯泡快速修复菜单处理它。

通过使用程序集重定向使其工作,如下所述: 只需在程序开头调用 FunctionsAssemblyResolver.RedirectAssembly() 即可。

using System.Reflection;
using System.Diagnostics;
using System.Linq;

public class FunctionsAssemblyResolver
{
    public static void RedirectAssembly()
    {
        var list = AppDomain.CurrentDomain.GetAssemblies().OrderByDescending(a => a.FullName).Select(a => a.FullName).ToList();
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var requestedAssembly = new AssemblyName(args.Name);
        Assembly assembly = null;
        AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
        try
        {
            assembly = Assembly.Load(requestedAssembly.Name);
        }
        catch (Exception ex)
        {
        }
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        return assembly;
    }

}

还有 4.2.0.0 版本错误,这已在 web.config 中为我修复:

  <dependentAssembly>
    <assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.6.0" />
  </dependentAssembly>
</assemblyBinding> 

我在 Visual Studio 2019 年通过执行清理解决方案命令修复了这个错误。

这通常发生在 visual studio 无法找出正确的 bindingRedirect 时。

最有可能的原因是块的版本与生成的库的版本不匹配。

要解决这个问题:

  1. 从包管理控制台执行:

    Get-Project –All | Add-BindingRedirect

    在配置文件中重新生成 assemblyBinding 配置

  2. 如果没有修复,则手动添加绑定重定向:

    <dependentAssembly>
        <assemblyIdentity name="System.ComponentModel.Annotations"    publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-X" newVersion="Y" />
    </dependentAssembly>
    

    其中:

    1. X是无法加载的版本,来自错误信息
    2. Y 是项目引用中的版本。要获取它,select 来自参考节点 的库,然后在 属性 窗格 上查找版本。

我通过实现辅助函数在开始时重定向程序集(在 中提出)来解决这个问题:

public static class FunctionsAssemblyResolver
{
    #region Public Methods

    public static void RedirectAssembly()
    {
        AppDomain.CurrentDomain.AssemblyResolve += ResolveAssemblyOnCurrentDomain;
    }

    #endregion Public Methods

    #region Private Methods

    private static Assembly ResolveAssemblyOnCurrentDomain(object sender, ResolveEventArgs args)
    {
        var requestedAssembly = new AssemblyName(args.Name);
        var assembly = default(Assembly);

        AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssemblyOnCurrentDomain;

        try
        {
            assembly = Assembly.Load(requestedAssembly.Name);
        }
        catch
        { }

        AppDomain.CurrentDomain.AssemblyResolve += ResolveAssemblyOnCurrentDomain;

        return assembly;
    }

    #endregion Private Methods
}

Linux 用户

如果您尝试从 linux 系统生成 .exe 文件,您可能需要安装 mono

参见 this link 如何在 ubuntu 20.04

上安装单声道

通过安装我想在解决方案中的所有项目中使用的相同 System.ComponentModel.Annotations 版本解决了这个问题。

请在您的 web.Configapp.Config 文件中添加以下 dependentAssembly

configuration下添加如下配置 --> runtime --> assemblyBinding节点下:

<dependentAssembly>
        <assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
      </dependentAssembly>

这实际上比破解配置文件要容易得多。破解配置文件有点可怕;你可能会错过一些东西!让 IDE 为您做 - 希望它能做对!

  1. 右键解决方案
  2. 单击管理解决方案的 Nuget 包...
  3. 搜索 System.ComponentModel.Annotations
  4. 在您的测试项目中勾选复选框并单击 安装

现在我的单元测试 运行!太棒了!

如果您的单元测试项目中有 app.config 个文件,您仍然可能需要使用@Guillaume 的回答。

归功于@MiguelSlv,因为我的案例与使用正确的绑定重定向有关。但是,请确保当您将应用程序部署到测试版或生产环境时,绑定重定向在您部署的 web.config 中(而不仅仅是在您的开发环境中)。我最终对 .NET Standard 2.0 中使用的 NuGet 包 System.ComponentModel.Annotations 5.0.0 使用了以下绑定重定向 class 项目正在被我的 **ASP.NET MVC Web 应用程序使用 (.NET Framework 4.7.1)

<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
</dependentAssembly>

请注意,4.2.1.0 是属性下显示的版本,而 5.0.0 是 NuGet 包版本。