如何解决Azure Function中的Newtonsoft.Json版本冲突问题?
这个问题的核心是Azure Functions Runtime自带的Newtonsoft.Json v9.0.0.0和你的函数依赖的v11.0.0.0被加载到了不同的应用域上下文,导致即使手动做了绑定重定向,也无法解决类型不兼容的问题(JObject来自不同版本的程序集,所以无法强制转换)。下面是经过验证的解决方案:
1. 用NuGet管理依赖(替代手动引用DLL)
不要手动将Newtonsoft.Json.dll放到bin目录并使用#r引用,而是通过function.proj文件让Azure Functions自动处理依赖和版本:
在你的函数目录下创建function.proj文件,内容如下:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net461</TargetFramework> </PropertyGroup> <ItemGroup> <!-- 替换为你实际使用的Microsoft.Azure.Devices.Shared版本 --> <PackageReference Include="Microsoft.Azure.Devices.Shared" Version="1.28.0" /> </ItemGroup> </Project>
这个文件会让Azure Functions自动下载Microsoft.Azure.Devices.Shared及其依赖的Newtonsoft.Json v11到函数的bin目录,确保版本匹配。
2. 添加全局绑定重定向配置
创建web.config文件放在函数目录下,强制所有程序集引用都使用Newtonsoft.Json v11,覆盖Runtime自带的v9:
<?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" /> <!-- 重定向所有旧版本到v11 --> <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
这一步是关键:Azure Functions Runtime会读取这个配置,确保所有加载的程序集都使用指定的Newtonsoft.Json版本,避免跨上下文的类型冲突。
3. 清理旧的引用和文件
- 移除代码中手动的
#r "bin\Newtonsoft.Json.dll"引用,因为function.proj已经自动处理了依赖引用。 - 删除函数bin目录下所有旧版本的
Newtonsoft.Json.dll,避免Runtime加载错误的版本。
4. 部署并验证
重新部署你的函数,查看日志:如果配置生效,你应该不会再看到JObject类型转换的异常,所有代码(包括IotHubProxy.GetTwinData)都会使用Newtonsoft.Json v11运行。
为什么之前的方法无效?
你手动在代码中做的应用域绑定重定向,无法覆盖WebJobs SDK(Azure Functions基于它)的程序集加载机制——Runtime自带的Newtonsoft.Json会被优先加载到默认上下文,而你的自定义DLL在另一个上下文加载,导致类型隔离。web.config的全局绑定重定向会被Runtime的加载器识别,从根源上统一版本。
内容的提问来源于stack exchange,提问作者Chris B. Behrens

