Newtonsoft.Json 参考抱怨 Azure Functions

Posted

技术标签:

【中文标题】Newtonsoft.Json 参考抱怨 Azure Functions【英文标题】:Newtonsoft.Json reference complaining on Azure Functions 【发布时间】:2016-05-19 22:54:25 【问题描述】:

我正在运行一个名为 SmsWebhook 的 Azure Functions。它调用外部程序集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).

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

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

【问题讨论】:

出于好奇,您能否在私有程序集引用之前添加以下指令:#r "Newtonsoft.Json.dll" 并重试? 【参考方案1】:

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

#r "Newtonsoft.Json"

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

Azure Functions C# developer reference

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

How can I use NuGet packages in my Azure Functions?

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


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

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

How do I use external assemblies with Microsoft Azure Function Apps?

【讨论】:

不幸的是,情况并非如此。我确实在我的run.csx 文件中添加了#r "Newtonsoft.Json"using Newtonsoft.Json;,尽管这些文件没有直接在文件中使用。我还按照您的建议添加了 project.json 和 NuGet 参考,但这对我没有帮助。 我的问题是无法加载 Json.NET 库,即使它在那里。 你有确切的异常抛出吗? 这就是我询问基于文件的引用(带有 DLL 扩展名)的原因,因为它会触发私有程序集加载,而不是与您期望的版本不匹配的共享程序集。可以试试吗? 另外,如果您在进行更改后仍然看到此问题,请尝试在设置下重新启动您的网站。【参考方案2】:

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

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

创建了一个简单类型的简单类库,该类库使用 Json.NET 序列化对象并返回 JSON 字符串。此程序集引用 Json.NET 8.0.3。结果包括它正在使用的 Json.NET 程序集版本 创建了一个函数,该函数使用#r "DependencyWithJsonRef.dll" 引用该类型only,并返回上述方法产生的结果 将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 并终止 non-scm w3wp 进程以查看是否有帮助。我很想知道这是否有效,因为如果有效,我们可以采取一些措施来改进它。

【讨论】:

谢谢!在我重新启动功能应用程序本身后(因为它基本上是一个网络应用程序),我不必有文件引用,#r "Newtonsoft.Json.dll",但#r "Newtonsoft.Json" 就足够了,如果我需要在run.csx 文件中使用它.如果我不需要它,则不需要参考。 但是,如果我不将Newtonsoft.Json.dll 程序集放入bin 目录,则会出错。我仍然很好奇,为什么我应该拥有这个程序集,即使它已经在内部引用了。 如果您引用共享程序集(简单名称),则不需要文件引用,但是,如果您需要特定版本,则将文件放在 bin 文件夹中并引用带有扩展名。【参考方案3】:

经过一些试错方法。我找到了问题所在。

@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 Functions 的 bin 目录后,它起作用了!


经验教训

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

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

干杯,

【讨论】:

我很高兴这对你有用!正如我之前的评论中提到的,这些步骤不应该是必需的。只需在函数中引用您的直接依赖项#r 并确保将预期版本的 Json.NET 部署到您的 bin 文件夹中即可按预期工作。不确定您是否要完成这些步骤,但进行上述设置会很有趣,确保您重新启动主机(以确保具有装配分辨率的干净石板)以查看是否有效。如前所述,我复制了您的场景,并且按照此处的描述工作。 另一个小说明;您不需要添加对间接依赖项的显式引用。所以#r "Newtonsoft.Json.dll"(或简单的名称)根本不需要。 @FabioCavalcante 你知道如何避免Could not load file or assembly 'log4net, Version=1.2.15.0吗?有什么地方可以添加绑定重定向?

以上是关于Newtonsoft.Json 参考抱怨 Azure Functions的主要内容,如果未能解决你的问题,请参考以下文章

如何遍历newtonsoft.json的JObject里的JSON数据

调用百度开发者API,程序集AipSdk所使用的Newtonsoft.Json,版本高于所引用的程序集Newtonsoft.Json

如何使用Newtonsoft.Json生成这样的json字符串

Newtonsoft.Json把含有集合的对象转换成json

没有服务参考的项目。错误:类型“Newtonsoft.Json.Linq.JToken”是一个不受支持的递归收集数据协定。

Newtonsoft.Json.dll 的施用怎么解决