Newtonsoft.Json引用抱怨Azure函数

时间:2016-05-19 22:54:25

标签: c# azure azure-functions

我正在运行名为SmsWebhook的Azure功能。它调用外部程序集AzureFunctionsSample.Services.dll中的方法,该方法引用Newtonsoft.Json 8.0.3

我的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).

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

如果我将外部装配中的所有逻辑移到Run.csx中,顺便说一下,它不会抱怨。

3 个答案:

答案 0 :(得分:17)

Json.Net可以简单地在Run.csx文件的顶部添加此行:

#r "Newtonsoft.Json"

如果您想知道Azure Functions托管环境自动添加哪些程序集,请参阅此文章:

否则,如果你想使用特定版本的Json.Net,你应该使用nuget包添加对Json.Net的引用:

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

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

如果您的外部依赖项在不使用nuget包的情况下引用Newtonsoft.Json,您可以查看此帖子,其中介绍了如何上传二进制文件:

答案 1 :(得分:5)

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

我将以下测试放在一起以重现您的场景:

  • 使用简单类型创建了一个简单的类库,该类使用Json.NET序列化对象并返回JSON字符串。该程序集引用了Json.NET 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并杀死非scm w3wp进程以查看是否有帮助。我很想知道这是否可行,因为如果有的话,我们可以做一些改进的事情。

答案 2 :(得分:2)

经过一些反复试验的方法。我发现了这里的问题。

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

bin

它实际上没有用。我已将这四个文件复制到Azure Functions的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> ,它实际上定义了程序集绑定重定向,如:

bin

将此配置文件复制到Azure Functions的Newtonsoft.Json目录后,它工作正常!

经验教训

  • 如果您的外部程序集也引用了#r "Newtonsoft.Json.dll" bin,请使用基于文件的参考。
  • 确保Azure Functions mm目录中存在程序集绑定重定向配置。

如果我还是错的话,纠正我。

干杯,