Azure函数 - 使用appsettings.json

时间:2016-11-23 15:36:16

标签: azure azure-functions

是否可以在Azure Functions中使用appsettings.json文件?

这里有环境变量的文档..

https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#environment-variables

..但是我们使用Octopus进行部署,并且非常希望控制appsettings版本。

我们尝试过使用

{
  "frameworks": {
    "net46": {
      "dependencies": {
        "Microsoft.Extensions.Configuration": "1.0.0",
        "Microsoft.Extensions.Configuration.Json": "1.0.0"
      }
    }
  }
}

但不断得到

2016-11-23T15:27:03.811(12,16):错误CS0012:类型'对象'在未引用的程序集中定义。您必须添加对程序集&System; Run.Runtime,Version = 4.0.0.0

的引用

即使能够通过Octopus提供/更新环境变量也足以满足我们的需求。

请告知。

7 个答案:

答案 0 :(得分:13)

根据您的需要,答案是肯定的! Azure Functions可以使用 appsettings.json 进行配置。但是,当请求函数时,Azure会执行一些排序序列。

1º)Azure将查找您在 .GetEnvironmentVariables(“[ KEY ]”)方法中使用的 KEYS ,通过键已在Azure功能设置

中的应用程序设置刀片上配置

2º)如果Azure无法通过“应用程序设置”键找到该配置,那么Azure将尝试在 appsettings.json 文件中查找您正在处理的函数的根文件夹

3º)最后,如果Azure无法在appsettings.json文件上的应用程序设置中找到此密钥,那么Azure将最后一次尝试查找web.config以查找此文件 appsettings 部分键。

为了您的感谢,您可以通过我的github repo上的示例找到这些配置:herehere

我希望这些信息对您有所帮助。

答案 1 :(得分:9)

根据对配置文件所做的更改,您应该只使用 local.settings.json ,因为 appsettings.json 已重命名为local.settings.json < / p>

参考变化: azure-functions-cli

答案 2 :(得分:4)

应用设置和连接字符串仅支持环境变量。

但是,您可以使用Azure资源管理器(ARM)模板配置功能应用程序的设置。这里有一个blog post,可以更详细地描述这一点。

答案 3 :(得分:2)

从Azure Functions主机版本2.0.14192.0和3.0.14191.0开始,可以使用配置源自定义。

要指定其他配置源,请在函数应用的StartUp类中重写ConfigureAppConfiguration方法。

using System.IO;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
    public class Startup : FunctionsStartup
    {
        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder 
builder)
        {
            FunctionsHostBuilderContext context = builder.GetContext();

            builder.ConfigurationBuilder
                .AddJsonFile(Path.Combine(context.ApplicationRootPath, 
"appsettings.json"), optional: true, reloadOnChange: false)
                .AddJsonFile(Path.Combine(context.ApplicationRootPath, $"appsettings. 
{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
                .AddEnvironmentVariables();
        }
    }
}

//更新csproject中的配置

<None Update="appsettings.json">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>      
</None>

<None Update="appsettings">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>

从Startup.Configure方法内部,可以使用以下代码将IConfiguration实例中的值提取到自定义类型中:

builder.Services.AddOptions<MyOptions>()
    .Configure<IConfiguration>((settings, configuration) =>
    {
        configuration.GetSection("MyOptions").Bind(settings);
    });

using System;
using Microsoft.Extensions.Options;

public class HttpTrigger
{
    private readonly MyOptions _settings;

    public HttpTrigger(IOptions<MyOptions> options)
    {
        _settings = options.Value;
    }
}

引用:https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#customizing-configuration-sources

答案 4 :(得分:1)

我们可以尝试和测试的方法:

  1. 在您的函数应用项目中创建一个 appsettings.json
  2. 您需要在从 FunctionsStartup 类继承的项目中添加一个 Startup.cs 类。这将公开一个方法 Configure(IFunctionsHostBuilder builder) 用于覆盖。
  3. 对于自定义级别的控制,我会说扩展 IFunctionsHostBuilder 类,可以说它是 (IFunctionsHostBuilderExtensions.cs) 并添加一个扩展方法以将新的配置生成器添加到相同的。这让我们可以控制在运行时如何配置 appsettings 设置。
  4. 完成后,您可以通过传递 appsettings 的整个文件路径或仅传递名称来调用新创建的扩展方法。(您可以在扩展方法中为您的 appsettings 配置基本路径以避免代码中的草率) .
  5. 构建扩展方法后,您将获得一个可供注入的服务,即 IConfiguration,它可以在代码库中的任何位置使用。
  6. 您还可以为应用设置添加多个提供程序,例如 Azure Key Vault、AWS Secret Manager 等。同样,您需要做的就是在 IFunctionsHostBuilderExtensions 类中添加一个扩展方法并在您的启动类中调用它们。< /li>
  7. 如果您想让事情更整洁,您可以围绕 IConfiguration 服务实现一个包装器以公开一个 GetSettings(string key) 方法,该方法将从中央集合返回您想要的设置IConfiguration 中的提供程序。

下面的一些代码片段:

/// <summary>
///     Represents the startup class of the function app.
/// </summary>
public class Startup : FunctionsStartup
{
    private const string LocalSettingFileGenericName = "appsettings";
    private const string LocalSettingFileExtension = "json";

    /// <summary>
    ///     Configures the host builder for the function app.
    /// </summary>
    /// <param name="builder">The function app host builder.</param>
    public override void Configure(IFunctionsHostBuilder builder)
    {
        try
        {
            builder.AddConfiguration((configurationBuilder) =>
            {
                var configuration = typeof(Startup).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>().Configuration;

                var configurationFileName = !string.Equals(configuration, "Release")
                    ? $"{LocalSettingFileGenericName}.{configuration.ToLowerInvariant()}.{LocalSettingFileExtension}"
                    : $"{LocalSettingFileGenericName}.{LocalSettingFileExtension}";

                var configurationSource = configurationBuilder
                    .AddJsonFile(configurationFileName, false, true)
                    .AddEnvironmentVariables();

                var partialConfigurationBuilder = configurationSource.Build();

                var keyVaultName = partialConfigurationBuilder.GetSection(ConfigurationKeys.KeyvaultName)?.Value;

                return configurationSource
                       .AddKeyVaultWithManagedIdentity(keyVaultName)
                       .Build();
            });

IFunctionBuilderExtensions.cs

 internal static class IFunctionsHostBuilderConfigurationsExtensions
{
    private const string keyVaultGenericUri = "https://{0}.vault.azure.net/";

    /// <summary>
    ///     Provides an extension method to add configuration provider.
    /// </summary>
    /// <param name="builder">The function app host builder.</param>
    /// <param name="configBuilderFunc">The delegate to pointing to configuration builder.</param>
    /// <returns>The function app host builder</returns>
    public static IFunctionsHostBuilder AddConfiguration(
        this IFunctionsHostBuilder builder,
        Func<IConfigurationBuilder, IConfiguration> configBuilderFunc)
    {
        var configurationBuilder = builder.GetBaseConfigurationBuilder();

        var configuration = configBuilderFunc(configurationBuilder);

        builder.Services.Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), configuration));

        return builder;
    }

    /// <summary>
    ///     Provides an extension method to add Azure Key Vault as a configuration provider.
    /// </summary>
    /// <param name="builder">The configuration builder.</param>
    /// <param name="keyvaultName">The azure key vault name.</param>
    /// <param name="authenticationClientId">The AAD application clientId.</param>
    /// <param name="authenticationClientSecret">The AAD application clientSecret.</param>
    /// <returns>The configuration builder.</returns>
    public static IConfigurationBuilder AddKeyVaultWithManagedIdentity(
        this IConfigurationBuilder builder,
        string keyvaultName)
    {
        if (string.IsNullOrWhiteSpace(keyvaultName))
        {
            return builder;
        }

        var serviceTokenProvider = new AzureServiceTokenProvider();
        var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(serviceTokenProvider.KeyVaultTokenCallback));

        var keyVaultUri = string.Format(keyVaultGenericUri, keyvaultName);

        builder.AddAzureKeyVault(
            keyVaultUri,
            keyVaultClient,
            new DefaultKeyVaultSecretManager());

        return builder;
    }

    private static IConfigurationBuilder GetBaseConfigurationBuilder(this IFunctionsHostBuilder builder)
    {
        var configurationBuilder = new ConfigurationBuilder();

        var descriptor = builder.Services.FirstOrDefault(
            service => service.ServiceType == typeof(IConfiguration));

        if (descriptor?.ImplementationInstance is IConfiguration configRoot)
        {
            configurationBuilder.AddConfiguration(configRoot);
        }

        var rootConfigurationBuilder = configurationBuilder.SetBasePath(GetCurrentDirectory());

        return rootConfigurationBuilder;
    }

    private static string GetCurrentDirectory()
    {
        var currentDirectory = Path.GetDirectoryName(
            Assembly.GetExecutingAssembly().Location);

        return currentDirectory.Replace("bin", "{Your settings directory}");
    }

包装器实现示例:

  /// <summary>
///     Represents the configuration settings provider class.
/// </summary>
public class ConfigurationSettings : IConfigurationSettings
{
    private readonly IConfiguration configurationSource;

    /// <summary>
    ///     Initializes the class of type <see cref="ConfigurationSettings"/>.
    /// </summary>
    /// <param name="configurationSource">The configuration source.</param>
    public ConfigurationSettings(
        IConfiguration configurationSource)
    {
        this.configurationSource = configurationSource;
    }

    ///<inheritdoc/>
    public T GetSetting<T>(string key)
    {
        try
        {
            if (!configurationSource.GetSection(key).Exists())
            {
                throw new ConfigurationDoesNotExistException(
                    $"The configuration with key {key} does not exist in appsetting or key vault.");
            }

            return (T)Convert.ChangeType(configurationSource.GetSection(key)?.Value, typeof(T));
        }
        catch (InvalidCastException)
        {
            throw;
        }
        catch (Exception)
        {
            throw;
        }
    }
}

答案 5 :(得分:0)

对于依赖项,您应该在函数中使用/创建project.json。在那里,您可以指定您的依赖项。 请检查: https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#package-management

例如:

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Microsoft.ProjectOxford.Face": "1.1.0"
      }
    }
   }
}

答案 6 :(得分:0)

在Azure Functions中,设置存储在local.settings.json中(如果您的解决方案中不存在此文件,则创建此文件,名称应与所提及的完全相同)。

一旦添加设置文件,就必须在下面提到的Run()方法下对其进行配置,

enter image description here

访问设置时,在下方使用

IConfigurationRoot config;
config["fromEmail"];

使用以下命令发布设置

func azure functionapp publish *YourAppName* --publish-local-settings -i

enter image description here