簡體   English   中英

Azure 函數 - 使用 appsettings.json

[英]Azure Functions - using appsettings.json

是否可以在 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.Runtime, Version=4.0.0.0 的引用

即使能夠通過 Octopus 提供/更新環境變量也足以滿足我們的需求。

請指教。

對於您的需求,答案是肯定的! Azure Functions 可以使用appsettings.json進行配置。 但是,當請求函數時,Azure 會執行一些排序順序。

1º)天青將尋找KEYS您在.GetEnvironmentVariables(“[KEY]”)方法中使用,通過對應用程序設置已配置的鑰匙刀片在天青功能的設置

2º) 如果 Azure 無法通過應用程序設置鍵找到該配置,則 Azure 將嘗試在appsettings.json文件中查找您正在處理的函數的根文件夾。

3º) 最后,如果 Azure 無法在應用程序設置或 appsettings.json 文件中找到此鍵,則 Azure 將最后一次嘗試查找 web.config 以查找此文件中的appsettings部分鍵。

為了您的欣賞,您可以通過我的 github 存儲庫上的示例找到這些配置: 這里這里

我希望這些信息對您有所幫助。

根據對配置文件所做的更改,您應該只使用local.settings.json,因為appsettings.json已重命名為 local.settings.json

更改參考: azure-functions-cli

應用程序設置和連接字符串僅支持環境變量。 不支持appsettings.json

但是,您可以使用 Azure 資源管理器 (ARM) 模板來配置函數應用的設置。 這是一篇博客文章,更詳細地描述了這一點。

從 Azure Functions 主機版本 2.0.14192.0 和 3.0.14191.0 開始提供配置源自定義。

若要指定其他配置源,請覆蓋函數應用的 StartUp 類中的 ConfigureAppConfiguration 方法。

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);
    });

函數類:使用系統; 使用 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

在 Azure Functions 中,設置存儲在 local.settings.json 中(如果您的解決方案中不存在,則創建此文件/名稱應與提到的完全相同)。

一旦你添加了設置文件,你必須在你的 Run() 方法下配置它,如下所述,

在此處輸入圖片說明

訪問設置時,請使用以下

IConfigurationRoot config;
config["fromEmail"];

使用以下命令發布設置

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

在此處輸入圖片說明

嘗試和測試方法,我們可以:

  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 類中添加一個擴展方法並在您的啟動類中調用它們。
  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;
        }
    }
}

也許這個簡單的解決方案會很有用:

[assembly: FunctionsStartup(typeof(AzureFunctions.Startup))]

namespace AzureFunctions;

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        var context = builder.GetContext();
        var config = context.Configuration; //Here you go!
    }

    public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
    {
        var 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); //For example enviroment name can be: Development
    }

}

對於依賴項,您應該在函數中使用/創建 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" } } } }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM