10

我正在运行一个名为SmsWebhook. 它调用外部程序集中的方法,该方法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,它不会抱怨。

4

3 回答 3

19

Json.Net 可以简单地参考在Run.csx文件顶部添加这一行:

#r "Newtonsoft.Json"

如果您想了解 Azure Functions 托管环境自动添加了哪些程序集,请参阅本文:

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

因此,您需要添加一个如下所示的 Project.json 文件:

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

如果您的外部依赖Newtonsoft.Json项在不使用 nuget 包的情况下引用,您可以查看这篇解释如何上传二进制文件的帖子:

于 2016-05-19T23:54:32.500 回答
5

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

我汇总了以下测试来重现您的场景:

  • 创建了一个简单类型的简单类库,该类库使用 Json.NET 序列化对象并返回 JSON 字符串。此程序集引用 Json.NET 8.0.3。结果包括它正在使用的 Json.NET 程序集版本
  • 创建了一个仅使用 a引用该类型的函数,#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 进程以查看是否有帮助。我很想知道这是否有效,因为如果有效,我们可以采取一些措施来改善这一点。

于 2016-05-20T18:00:53.723 回答
2

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

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

#r "Newtonsoft.Json.dll"

它实际上没有用。我已将这四个文件复制到 Azure Functions 的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 Functionsbin目录后,它工作了!


得到教训

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

纠正我,如果我仍然错了。

干杯,

于 2016-05-20T02:53:43.177 回答