Azure Functions中替代<codeBase>解决Newtonsoft.Json版本冲突
这个问题我之前在处理Azure Functions项目时踩过不少坑,确实因为没有传统的web.config/app.config文件,版本冲突的处理逻辑和常规.NET应用不太一样。下面给你几个可行的解决方案,按推荐优先级排序:
1. 用NuGet自动生成绑定重定向(最推荐)
对于.NET Core/.NET 5+的Azure Functions项目,你不需要手动维护配置文件,直接通过项目文件(.csproj)开启绑定重定向自动生成即可:
- 打开你的函数项目的
.csproj文件,添加以下配置:
<PropertyGroup> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> </PropertyGroup>
- 重新构建项目,系统会自动生成一个
[你的程序集名称].runtimeconfig.json文件,里面包含了所有必要的绑定重定向规则。 - 部署时确保这个
runtimeconfig.json文件和函数的DLL一起上传到Azure,Functions运行时会自动读取这个文件来处理程序集版本绑定。
如果自动生成的规则不符合需求,你也可以手动编辑runtimeconfig.json,在configProperties下添加自定义的绑定规则,比如:
{ "runtimeOptions": { "configProperties": { "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, "Microsoft.NETCore.DotNetHostPolicy.SetupConfigurationBindingRedirects": true }, "assemblyBinding": { "dependencies": [ { "name": "Newtonsoft.Json", "publicKeyToken": "30ad4fe6b2a6aeed", "version": "13.0.0.0", "culture": "neutral" } ] } } }
2. 针对.NET Framework版Functions:直接用app.config
如果你的Azure Functions是基于.NET Framework开发的,其实可以直接添加app.config文件到项目中:
- 在项目里新建
app.config,添加常规的<assemblyBinding>和<codeBase>节点,比如:
<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-13.0.0.0" newVersion="13.0.0.0" /> <codeBase version="13.0.0.0" href="bin/Newtonsoft.Json.dll" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
- 右键
app.config文件,设置复制到输出目录为如果较新则复制。部署时这个文件会被复制到函数目录,Functions运行时会像常规.NET应用一样读取它的绑定规则。
3. 手动注册AssemblyResolve事件(备选方案)
如果上面的方法都不适用(比如一些特殊的隔离场景),可以通过代码手动拦截程序集加载请求,指定要加载的版本:
- 在你的函数类的静态构造函数里,或者Startup类的配置方法中,注册
AppDomain.CurrentDomain.AssemblyResolve事件:
using System; using System.IO; using System.Reflection; public class MyFunction { static MyFunction() { AppDomain.CurrentDomain.AssemblyResolve += ResolveNewtonsoftJson; } private static Assembly ResolveNewtonsoftJson(object sender, ResolveEventArgs args) { var assemblyName = new AssemblyName(args.Name); // 只处理Newtonsoft.Json的加载请求 if (assemblyName.Name.Equals("Newtonsoft.Json", StringComparison.OrdinalIgnoreCase)) { // 指定要加载的DLL路径,这里假设目标版本的DLL在函数根目录 var targetPath = Path.Combine(AppContext.BaseDirectory, "Newtonsoft.Json.dll"); return Assembly.LoadFrom(targetPath); } // 其他程序集返回null,让系统按默认逻辑加载 return null; } // 你的函数逻辑 [FunctionName("MyFunction")] public static async Task<IActionResult> Run(...) { // ... } }
- 部署时确保你想要的版本的
Newtonsoft.Json.dll被复制到函数输出目录,并且设置正确的复制属性。
额外注意事项
- 如果你用的是**.NET Isolated模型**的Azure Functions,程序集加载逻辑由自定义的
AssemblyLoadContext管理,你可以在Program.cs中配置自定义的加载规则,或者同样依赖runtimeconfig.json的绑定重定向。 - 部署前一定要在本地测试,确保绑定规则生效,避免出现运行时程序集加载失败的问题。
内容的提问来源于stack exchange,提问作者bech




