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

时间:2019-09-12 15:56:06

标签: .net load-testing system.componentmodel assemblyversions

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

我有一个负载测试项目(带有一个.loadtest文件和一个从Microsoft.VisualStudio.TestTools.WebTesting.WebTest继承的类)。它必须以.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。

enter image description here

现在,我可以通过删除NuGet程序包引用并在Packages文件夹中添加对该dll的手动引用来将项目强制为正确的版本(似乎是4.2.1.0),然后再进行链下的另一个项目拒绝接受我提供的hintPath,并且默认使用其他位置和版本:

enter image description here

因此,我不能强制使用我想要的dll的实际版本和位置的所有项目。

我只是想知道是否有人可以提出任何可能有助于解决问题的措施,因为我对于如何迫使整个事情使用正确的版本感到有些困惑。通过绑定重定向,或者让所有项目接受我提供的dll的路径。

3 个答案:

答案 0 :(得分:1)

对于以后遇到此问题的任何人,我最终还是通过绑定重定向最终解决了这个问题。重新阅读链接到的github线程使我意识到,从技术上讲,软件包中的版本号实际上没有问题,并且绑定重定向是“正确的”解决方案。

因此,我遇到的实际问题是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);
    }
}

答案 1 :(得分:1)

这最近也发生在我身上。我通过将.NET Framework增加到目标> = 4.7.2,并将AutoGenerateBindingRedirects,GenerateBindingRedirectsOutputType设置为true,来解决此错误。

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

因此,如果仍然有意义,请考虑更改目标框架。

答案 2 :(得分:0)

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