C# Azure函数上的Newtonsoft.Json引用

C# Azure函数上的Newtonsoft.Json引用,c#,azure,azure-functions,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<Htt

我正在运行一个名为
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)
{
    ...
}
我在
bin
目录下手动添加了相同版本的
Newtonsoft.Json.dll
,但仍然得到了相同的错误。为什么它在
Newtonsoft.Json.dll
文件中抱怨


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

Json.Net只需在
Run.csx
文件顶部添加这一行即可:

#r "Newtonsoft.Json"
如果您想知道Azure函数宿主环境自动添加了哪些程序集,请参阅本文:

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

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

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Newtonsoft.Json": "8.0.3"
      }
    }
   }
}
如果您的外部依赖项引用了
Newtonsoft.Json
,而没有使用nuget软件包,那么您可以看看这篇文章,它解释了如何上传二进制文件:


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

@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
    目录中存在程序集绑定重定向配置
如果我还是错的话,请纠正我


干杯,

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

为了重现您的场景,我进行了以下测试:

  • 创建了一个简单类库,其简单类型使用Json.NET序列化对象并返回Json字符串。此程序集引用Json.NET 8.0.3。结果包括它正在使用的Json.NET程序集版本
  • 创建了一个函数,该函数使用
    #r“DependencyWithJsonRef.dll”
    仅引用该类型,并返回由上述方法生成的结果
  • DependencyWithJsonRef.dll
    Newtonsoft.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进程,看看这是否有帮助。我很想知道这是否奏效,因为如果奏效,我们可以做一些事情来改进它。

出于好奇,您能否在您的私有程序集引用之前添加以下指令:#r“Newtonsoft.Json.dll”并重试?不幸的是,情况并非如此。我添加了
#r“Newtonsoft.Json”
使用Newtonsoft.Json在我的
run.csx
文件中,即使这些文件中没有直接使用。我还添加了
project.json
,使用了您建议的NuGet引用,但这对我没有帮助。我的问题是,json.NET库无法加载,即使它在那里。您是否有引发的确切异常?这就是为什么我询问基于文件的引用(具有DLL扩展名)因为这将触发私有程序集加载,而不是与预期版本不匹配的共享程序集。你能试一试吗?另外,如果你在做出改变后仍然看到问题,请尝试在“设置”下重新启动你的网站。我很高兴这对你有用!正如我在前面的评论中提到的,这些步骤不应该是必需的。只需在函数中使用直接依赖关系#r引用,并确保预期版本的Json.NET部署到bin文件夹中,就可以正常工作。不确定是否要执行这些步骤,但有必要进行上述设置,确保重新启动主机(以确保具有程序集分辨率的干净记录)以查看是否有效。如前所述,我复制了您的场景,并按照此处所述进行了操作;您不需要向间接依赖项添加显式引用。因此,根本不需要
#r“Newtonsoft.Json.dll”
(或具有简单名称)。@FabioCavalcante您知道如何避免
无法加载文件或程序集的log4net,Version=1.2.15.0
?任何地方
{
    "Prop1":"Test",
    "Prop2":1,
    "AssemblyName": "Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed"
}