如何读取 Azure Function 应用程序中的配置 json 文件

How to read a config json file inside a Azure Function app

我有一个 json 配置文件,我想从 Azure 函数内部读取它。默认情况下,我们有 localsettings.json 文件,但我还需要一个 Json 配置文件来读取我的函数代码。最好的方法是什么,到目前为止,对于我的其他项目,我可以通过下面的代码阅读,但这在 Azure 函数内部不起作用。

 var builder = new ConfigurationBuilder()
        .SetBasePath(Path.Combine(Root))
        .AddJsonFile("DataFileConfiguration.json", optional: false);
         var config = builder.Build();
         var tableStorageOutput = new TableStorageConfiguration();
         config.GetSection("TableStorageRule").Bind(tableStorageOutput);

在解决方案资源管理器中右键单击 'DataFileConfiguration.json' 文件 -> 属性 -> 复制到输出文件夹 = 'Copy always'

天哪,这太长了,我在底部放了一个 TL;DR:POC

这花了我一段时间才弄清楚我是在什么时候处理它的,所以我决定创建一个关于这个的小指南。

  1. 创建元数据文件:我们称它为appsettings.json只是因为我们以前都使用C# web APIs并且习惯了,但是你可以随便叫它。 确保在构建解决方案时始终复制此文件。右键单击文件 Solution Explorer => Properties => Copy to Output Directory => Copy always

  2. 创建一个 class 强类型您的应用程序设置 json 文件

    public class AppSettings
    {
        public string SomeValue { get; set; }
    }
  1. 在继承自 FunctionsStartup
  2. .csproj 中创建一个 Startup.cs 文件
    [assembly: FunctionsStartup(typeof(FunctionApp.Startup))]
    
    namespace FunctionApp
    {

        public class Startup: FunctionsStartup
        {
            private IConfigurationRoot Config = null;

            private IConfigurationRoot FunctionConfig(string appDir) =>
                Config ??= new ConfigurationBuilder()
                    .AddJsonFile(Path.Combine(appDir, metaDataFileName), optional: false, reloadOnChange: true)
                .Build();
        }
    }

感谢 Anthony BrenelièreReference

实施Configure方法。这是您将 bootstrap 所有 DI 服务的地方,例如:

    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddTransient<IService, SomeService>();
        //some other services
    }  

在您的 Configure 方法中将您的 IOptions 定义为:

builder.Services.AddOptions<AppSettings>()
                .Configure<IOptions<ExecutionContextOptions>>((settings, exeContext) =>
                FunctionConfig(exeContext.Value.AppDirectory).Bind(settings));

现在您终于可以访问您的数据了:

    public class AzureFunction
    {
        private readonly AppSettings AppSettings;
        public AzureFunction(IOptions<AppSettings> appsettings)
        {
            AppSettings = appsettings.Value;
        }

        [FunctionName("AzureFunction")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
            ILogger log)
        {
            var result = AppSettings.SomeValue;
            return new OkObjectResult(result);
        }
    }

奖金轨道:据我所知,没有像在 Web API 中那样在启动 class 的构造函数中注入 appsettings.json 文件的优雅方法。

    //we cannot do this in azure function (yet)
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

那么,我如何访问 SQL ConnectionString?我在进入 Configure 方法时需要它,这样我就可以像这样注册服务:

            builder.Services.AddDbContext<SqlDbContext>(
                options => options.UseSqlServer(//howww???, I don't want to hard code it));

好吧,我个人唯一能让它起作用的方法是:

本地开发: 在local.settings.json中定义为

  "ConnectionStrings": {
    "SqlConnectionString": "some connectionstring"
  }

并在 Startup class 中通过 Environment.GetEnvironmentVariable

访问它
    Environment.GetEnvironmentVariable("ConnectionStrings:SqlConnectionString")    

对于 Azure Web Apps:, 如果您正在部署到应用服务,连接字符串应该定义在 azure portal => your azure function => settings\configuration使用与 json 文件相同的密钥,以便能够同时在两种环境 (local/cloud) 上工作。

但是等等,还有更多:

Azure App 服务要求您按照上图在 Azure 门户中定义连接字符串,没什么大不了的吧?这让 一些 感觉他们指挥如何设置。毕竟,他们只会使用提供的密钥在应用服务中设置环境变量,在我的示例中 SqlConnectionString.

不,他们使用密钥 SQLCONNSTR_{name} 配置您的连接字符串。你可以检查这个,如果你在 advance tools 中转到 kudu console 并执行 >cmd set 来列出你的应用程序服务的所有环境变量。

Big shout out to @johnwc for that pointer

TL;DR:我在这里创建了一个小型 POC 来实现此目的:link