37

我在使用 Azure 表存储时遇到了一个非常特殊的问题。我在 Visual Studio 2012 中有一个 .NET 4.5 项目,我在其中处理所有 Azure 表存储功能。这个项目/dll 被另外两个项目引用,我的 MVC 网站和我的 Azure Worker Role。(我在我的机器上的 Azure 模拟器下运行,但是当我将它部署到云时也会发生)

我在保存或检索记录时调用了以下函数:

internal static CloudTable GetTable(CloudStorageAccount storageAccount, string tableReference)
{
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

    CloudTable table = tableClient.GetTableReference(tableReference);
    table.CreateIfNotExists();

    return tableClient.GetTableReference(table.Name);
}

在我的 MVC 网站中,我有一个函数可以将记录保存到 Azure 存储表中,然后在我的 Azure Worker Role 中有一个可以读取记录的服务。

所以两者都使用相同的 dll 进行存储和检索,但是我的 MVC 项目在保存记录时没有问题,但是在我的 Azure Worker 角色服务中,当它尝试检索记录时会在尝试执行“table.CreateIfNotExists() ;"。

无法加载文件或程序集“Microsoft.Data.OData,Version=5.2.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。(来自 HRESULT 的异常:0x80131040)

我已经做了以下事情:

  1. 将所有 NuGet 包从解决方案级别更新到最新版本
  2. 我检查了每个项目参考,以确保没有旧的 dll 或以前的版本,特别是 System.Spatial、Microsoft.WindowsAzure.Configuration、Microsoft.WindowsAzure.ServiceRuntime 和 Microsoft.ServiceBus、Microsoft.WindowsAzure.Storage, Microsoft.Data.Edm 和 Microsoft.Data.OData
  3. 我什至从头开始创建了一个新的云服务和 WorkerRole 项目,以确保它不是当前 WorkerRole 项目中损坏的东西。

我没有将 dll 回滚到 5.2,因为我在其他项目中遇到了太多问题,我使用了从 5.3 开始的特定功能。

我目前在 5.5 上运行所有 dll。

当我运行在此处找到的 AsmSpy.exe 实用程序时,我得到以下输出,我不确定如何解释 100%。

> Reference: Microsoft.Data.Edm
>         5.5.0.0 by Microsoft.Data.OData
>         5.5.0.0 by Microsoft.Data.Services.Client
>         5.5.0.0 by Microsoft.WindowsAzure.ActiveDirectory.GraphHelper.2013_04_05
> Reference: System.Spatial
>         5.5.0.0 by Microsoft.Data.OData
>         5.5.0.0 by Microsoft.Data.Services.Client Reference: Microsoft.Data.OData
>         5.5.0.0 by Microsoft.Data.Services.Client
>         5.2.0.0 by Microsoft.WindowsAzure.Storage   <-- THIS SEEMS TO BE THE ONE THAT IS CAUSING ISSUES

我如何解释它,是 Microsoft.WindowsAzure.Storage dll 引用了 Microsoft.Data.OData dll 的 V 5.2.0.0,但如果这是问题所在,我该如何解决?根据我在 Storage dll 上看到的文档,它应该引用 5.4 及更高版本,而不是 5.2 ...?

4

5 回答 5

40

为这样一个容易解决的问题打开问题对您没有帮助。

将以下附加配置放入各自的配置文件中(MVC 为 web.config,worker 角色为 app.config):

 <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

请注意,runtimesection 是configuration根元素的直接后代!我很确定你的 web.config 中已经有了这个部分,因为 MVC4 使用它来重新绑定System.Web.MVC对最新版本的所有引用。

我个人不希望 SDK 会随着每个引用库的每个新版本而更新!这将是疯狂的...

于 2013-06-04T06:31:07.983 回答
16

我有一个非常相似的问题,但在这种情况下,它的异常消息是;

无法加载文件或程序集 'Microsoft.Data.OData, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。(来自 HRESULT 的异常:0x80131040)

请注意,它正在尝试加载 OData 程序集的 v5.5.0.0。

在对 ILSpy ( http://www.ilspy.net ) 进行了一番挖掘之后,我发现 Microsoft.WindowsAzure.Storage 2.0.0.0 明确引用了 Microsoft.Data.OData 5.2.0.0 - 我没有,因为我的版本是5.5.0.0。

所以解决方案是使用 NuGet 包管理器卸载 Microsoft.WindowsAzure.Storage,这反过来又卸载了 Microsoft.Data.OData 5.5。然后再次使用 NuGet 包管理器,重新安装 Microsoft.WindowsAzure.Storage,它确定它需要 Microsoft.Data.OData 5.2 并安装它。

并回到工作解决方案。

于 2013-06-25T18:12:52.057 回答
11

每当您通过 NuGet 更新包或添加新包并最终出现“无法加载文件或程序集...”问题时,您通常可以解决此问题。

打开包管理器控制台VS 2012 工具/库包管理器/包管理器控制台)。一旦打开包管理器控制台的外壳,请运行以下命令:

添加绑定重定向

注意:请注意,NugGet 示例在其示例的末尾添加了一个“s”,这Add-BindingRedirect不是一个有效的命令。

这将执行以下操作:

检查项目输出路径中的所有程序集,并在需要时将绑定重定向添加到应用程序配置 (app.config) 文件或 Web 配置 (web.config) 文件。

您可以在以下位置查看包管理器控制台的完整文档:http://nuget.codeplex.com/wikipage?title=Package%20Manager%20Console%20Command%20Reference%20(v1.3)

除了您在 astaykov 的回答中看到的两个条目之外,还为我的项目添加了以下条目。

  <dependentAssembly>
    <assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
  </dependentAssembly>
于 2013-07-30T16:39:17.187 回答
1

我今天有类似的问题。我发现的唯一区别是我的云应用程序正在寻找(但未能找到)Microsoft.Data.OData in Version= 5.2.0.0

使用 Visual Studio 对象浏览器,我发现我的解决方案使用了该位置的库:

C:\Program Files (x86)\Microsoft WCF 数据服务\5.0\bin\.NETFramework

驻留在那里的 Microsoft.Data.OData 库在版本中。5.0.0.0所以用5.2.0.0覆盖它解决了这个问题。

PS 我之前为 Windows Store Apps 安装了 WCF 数据服务工具,希望能解决这个问题,因此您的应用程序可能会从其他来源获取它。如果是这种情况,您有两种选择:

  1. 从此处安装适用于 Windows 应用商店应用的 WCF 数据服务工具并使用上述解决方案。

  2. 使用 Visual Studio 对象浏览器查找当前对您的项目可见的 OData 库版本以及它们的存储位置。接下来,您需要覆盖它们的不正确版本。

于 2013-08-27T11:33:45.187 回答
0

我也有类似的问题,但我没有使用 Azure,也没有指向 5.2 的硬编码参考。但它通过确保 .svc 中的文本指向正确的程序集来解决(在找到这篇文章之后):

<%@ ServiceHost Language="C#"
      Factory="System.Data.Services.DataServiceHostFactory,
      Microsoft.Data.Services, Version=5.6.0.0,
      Culture=neutral, PublicKeyToken=31bf3856ad364e35"

服务="MVC4WCFDataServiceFE5.NorthWindService" %>

请注意我以前没有的Version=5.6.0.0 。

于 2014-07-24T19:39:36.687 回答