是否可以在Azure Functions中使用appsettings.json文件?
这里有环境变量的文档..
..但是我们使用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提供/更新环境变量也足以满足我们的需求。
请告知。
答案 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上的示例找到这些配置:here和here
我希望这些信息对您有所帮助。
答案 1 :(得分:9)
根据对配置文件所做的更改,您应该只使用 local.settings.json ,因为 appsettings.json 已重命名为local.settings.json < / p>
参考变化: azure-functions-cli
答案 2 :(得分:4)
应用设置和连接字符串仅支持环境变量。 1}}不受支持。
但是,您可以使用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;
}
}
答案 4 :(得分:1)
我们可以尝试和测试的方法:
下面的一些代码片段:
/// <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)