Newtonsoft.Json引用抱怨Azure函数



我正在运行一个名为SmsWebhook的Azure函数。它调用外部程序集中引用Newtonsoft.Json 8.0.3的方法AzureFunctionsSample.Services.dll

我的Run.csx的详细信息如下:

#r "AzureFunctionsSample.Services.dll"
using System.Net;
using AzureFunctionsSample.Services
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
...
}

在上面的Run()方法中,我创建了一个实例并调用该实例中的一个方法。然而,每当我调用该方法时,我都会收到以下错误:

2016-05-19T13:41:45  Welcome, you are now connected to log-streaming service.
2016-05-19T13:41:46.878 Function started (Id=64fccf0c-d0ef-45ef-ac1c-7736adc94566)
2016-05-19T13:41:46.878 C# HTTP trigger function processed a request. RequestUri=https://ase-dev-fn-demo.azurewebsites.net/api/smswebhook
2016-05-19T13:41:46.878 Function completed (Failure, Id=64fccf0c-d0ef-45ef-ac1c-7736adc94566)
2016-05-19T13:41:46.894 Exception while executing function: Functions.SmsWebhook. Microsoft.Azure.WebJobs.Script: One or more errors occurred. AzureFunctionsSample.Services: Could not load file or assembly 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).

我手动在bin目录下添加了相同版本的Newtonsoft.Json.dll,但仍然收到相同的错误。为什么它在Newtonsoft.Json.dll文件中抱怨?

顺便说一句,如果我把外部程序集中的所有逻辑都移到Run.csx中,它就不会抱怨了。

Json。Net可以简单地引用在Run.csx文件的顶部添加这一行:

#r "Newtonsoft.Json"

如果你想知道Azure函数托管环境自动添加了哪些程序集,请参阅本文:

  • Azure函数C#开发者参考

否则,如果要使用特定版本的Json。Net,您可能应该添加对Json的引用。网络使用nuget包:

  • 如何在我的Azure功能中使用NuGet包

所以你需要添加一个Project.json文件,如下所示:

{
"frameworks": {
"net46":{
"dependencies": {
"Newtonsoft.Json": "8.0.3"
}
}
}
}

如果你的外部依赖引用Newtonsoft.Json而不使用nuget包,你可以看看这篇文章,它解释了如何上传你的二进制文件:

  • 如何将外部程序集与Microsoft Azure Function Apps一起使用

@JustIntronicles,我在这里添加这个作为参考答案,但预期的行为应该是从bin文件夹中解析私有程序集的间接依赖关系,正如预期的那样。

我做了以下测试来重现你的场景:

  • 创建了一个使用Json的简单类型的简单类库。NET来序列化对象并返回JSON字符串。此程序集引用Json。净额8.0.3。结果包括Json。它正在使用的.NET程序集版本
  • 创建了一个函数,该函数使用#r "DependencyWithJsonRef.dll"仅引用类型,并返回由上述方法生成的结果
  • DependencyWithJsonRef.dllNewtonsoft.Json.dll(8.0.3)部署到我的函数的bin文件夹

调用函数会产生预期的结果。

以下是功能,供参考:

#r "DependencyWithJsonRef.dll"
using System.Net;
public static string Run(HttpRequestMessage req, TraceWriter log)
{
var myType = new DependencyWithJsonRef.TestType();
return myType.GetFromJson();
}

正如您所看到的,不需要显式引用间接依赖项(Json.NET)。

这是我得到的输出:

{
"Prop1":"Test",
"Prop2":1,
"AssemblyName": "Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed"
}

快速提示:您可能需要检查的一件事,特别是如果您在开发函数时更新了该依赖项,那就是没有缓存程序集结果。确保从头开始的一个可靠方法是(在部署函数和程序集之后)转到Kudu并终止非scmw3wp进程,看看这是否有帮助。我很想知道这是否奏效,因为如果真的奏效了,我们可以做一些改进。

经过一些尝试和错误的方法。我发现问题出在这里。

@FabioCavalcante使用基于文件的参考给了我一个提示

#r "Newtonsoft.Json.dll"

它实际上没有起作用。我已经将这四个文件复制到Azure函数的bin目录:

  • AzureFunctionsSample.Services.dll
  • AzureFunctionsSample.Services.pdb
  • Newtonsoft.Json.dll
  • Newtonsoft.Json.xml

即使我做了基于文件的引用,它仍然给了我同样的错误。然后,我找到了另一个文件AzureFunctionsSample.Services.dll.config,它实际上定义了程序集绑定重定向,比如:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

在我将此配置文件复制到Azure函数的bin目录后,它就工作了!


经验教训

  • 如果外部程序集也有对Newtonsoft.Json#r "Newtonsoft.Json.dll"的引用,请使用基于文件的引用
  • 请确保Azure函数的bin目录中存在程序集绑定重定向配置

如果我还是错了,请纠正我。

干杯,

最新更新