You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动