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

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

我知道有人问过这个问题,但我已经尝试了所有我能找到的建议解决方案。

我有一个负载测试项目(带有 .loadtest 文件和继承自 Microsoft.VisualStudio.TestTools.WebTesting.WebTest 的 class)。它必须针对 .Net Framework(版本 4.6.1)而不是 .Net Core。

它引用了一个以 .Net Standard 2.0 为目标的项目,加载项目和 .Net Standard 项目都添加了 System.ComponentModel.Annotations(版本 4.5.0)Nuget 包。

当我尝试 运行 负载测试本身时,我收到以下异常:

System.IO.FileNotFoundException
  Message=Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

我已经尝试将 app.config 文件添加到具有绑定重定向的负载测试项目中,但这对异常没有任何影响。

我无法降到 NuGet 包的 4.4.1 版,因为其他地方的其他项目依赖于它是 4.5 版。

I have read that there is a problem with the versioning in this package。事实上,当我检查构建的 .Net Standard 项目 dll 的依赖项时,它似乎不是针对指定的 4.5.0,而是针对版本 4.2.0.0。

现在我可以通过删除 NuGet 包引用并在 Packages 文件夹中添加对 dll 的手动引用来将项目强制为正确的版本(似乎是 4.2.1.0),但随后另一个项目失败了链拒绝接受我给它的hintPath,并默认为不同的位置和版本:

所以我不能强制我需要的所有项目都使用我想要的 dll 的实际版本和位置。

只是想知道是否有人可以建议任何可能对这里有帮助的行动方案,因为我对如何强制整个事情使用正确的版本有点不知所措。通过绑定重定向,或让所有项目接受我提供的 dll 路径。

对于将来遇到此问题的任何人,我最终确实通过绑定重定向解决了这个问题。重新阅读我链接到的 github 线程让我意识到包中的版本号实际上在技术上没有问题,绑定重定向是 "correct" 解决方案。

所以我遇到的实际问题是 Microsoft 负载测试框架不会加载您添加到项目中的任何 app.config,而是在 Program Files 中的某处使用 QTAgent_40.exe.Config 文件文件夹。所以我必须在负载测试初始化​​时手动解析程序集。此博客有执行此操作的代码:http://macmillan.scot/post/visual-studio-web--load-tests-can%E2%80%99t-access-appconfig

但我稍微修改了代码以包括版本检查:

public static void Resolve()
{
    LoadConfig();
    AppDomain.CurrentDomain.AssemblyResolve +=  delegate (object sender, ResolveEventArgs e)
    {
        var requestedName = new AssemblyName(e.Name);

        foreach (XmlNode assembly in assemblyBindingFromAppContext)
        {
            var assemblyIdentityNameNode = assembly.SelectSingleNode("./bindings:assemblyIdentity/@name", docNamepace);
            var bindingRedirectNewVersionNode = assembly.SelectSingleNode("./bindings:bindingRedirect/@newVersion", docNamepace);

            if (assemblyIdentityNameNode != null && bindingRedirectNewVersionNode != null)
            {
                var assemblyName = assemblyIdentityNameNode.Value;
                var specifiedVersion = bindingRedirectNewVersionNode.Value;

                if (string.Equals(requestedName.Name, assemblyName, StringComparison.OrdinalIgnoreCase))
                {
                    var resolvedAssembly = Assembly.LoadFrom(Invariant($"{assemblyName}.dll"));
                    var resolvedAssemblyVersion = resolvedAssembly.GetName().Version;

                    if (string.Equals(resolvedAssemblyVersion.ToString(), specifiedVersion, StringComparison.OrdinalIgnoreCase))
                    {
                        return resolvedAssembly;
                    }
                }
            }
        }

        return null;
    };
}

private static void LoadConfig()
{
    var configFileName = Path.Combine(Environment.CurrentDirectory, Invariant($"{Assembly.GetExecutingAssembly().ManifestModule.Name}.config"));
    var xmlDoc = new XmlDocument();
    xmlDoc.Load(configFileName);

    docNamepace = new XmlNamespaceManager(xmlDoc.NameTable);
    docNamepace.AddNamespace("bindings", "urn:schemas-microsoft-com:asm.v1");

    if (xmlDoc.DocumentElement != null)
    {
        assemblyBindingFromAppContext = xmlDoc.DocumentElement.SelectNodes("//bindings:dependentAssembly", docNamepace);
    }
}

最近我也遇到了这种情况。我通过将 .NET 框架增加到目标 >= 4.7.2 并将 AutoGenerateBindingRedirects、GenerateBindingRedirectsOutputType 设置为 true 来修复此错误。

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

因此,如果它仍然相关,请考虑更改目标框架。

我遇到这个问题是因为我在使用属性验证的模型项目上使用 System.ComponentModel.Annotations。该项目在 ASP.NET API 项目和 wpf 项目之间共享。 System.COmponentModel.ANnotations 更新到 v4.7.0 后,问题已解决。