Azure Functions 数据库连接字符串
Azure Functions Database Connection String
如何在 Azure 函数中添加或访问 app.config
文件以添加数据库连接字符串?
如果您不应该添加 app.config
并且有更好的方法访问外部数据库来执行函数,请告诉我最佳做法。谢谢!
执行此操作的最佳方法是从 Azure 门户添加连接字符串:
- 从您的函数应用程序 UI,单击函数应用程序设置
- 设置/应用设置
- 添加连接字符串
然后它们将使用与在 web.config 中相同的逻辑可用,例如
var conn = System.Configuration.ConfigurationManager
.ConnectionStrings["MyConn"].ConnectionString;
或者,如果您使用的是非 .NET 语言,则可以改用应用程序设置,它会在运行时成为您的函数可以访问的简单环境变量。
我相信常见的做法是为 azure 函数使用环境变量,然后您可以在 Azure 函数中设置环境变量:
(功能应用设置 -> 配置应用设置 -> 应用设置部分)
如果您也可以让我们知道您使用的是哪种语言,也许会更有帮助?
Jan_V 几乎 成功了,这促使我在 local.settings.json
中对此进行了试验
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": ""
},
"ConnectionStrings": {
"MyConnectionString": "[YourConnectionStringHere]"
}
}
这允许您使用我们都习惯的ConfigurationManager.ConnectionStrings[]
。
var sqlConnection = ConfigurationManager
.ConnectionStrings["MyConnectionString"].ConnectionString;
我在这里经历了几个类似的问题和答案。他们中的许多人要么具有误导性,要么假设每个人都处于同一水平并且理解 azure 函数是如何工作的。像我这样的新手没有答案。我想在这里逐步总结我的解决方案。
最重要的是我们了解local.settings.json文件
不适合 AZURE。 运行 你的应用在本地就像名字一样
明明说所以解决方案与这个文件无关。
App.Config 或 Web.Config 不适用于 Azure 函数连接字符串。如果您有数据库层库,则无法像在 Asp.Net 应用程序中那样使用其中任何一个覆盖连接字符串。
为了使用,您需要在 Azure 函数的 Application Settings
下的 Azure 门户上定义连接字符串。有
连接字符串。在那里你应该复制你的 DBContext 的连接字符串。如果是 edmx,它将如下所示。有连接类型,我使用它 SQlAzure 但我测试了自定义(有人声称只适用于自定义)适用于两者。
metadata=res:///Models.myDB.csdl|res:///Models.myDB.ssdl|res://*/Models.myDB.msl;provider=System.Data.SqlClient;provider
connection string='data source=[yourdbURL];initial
catalog=myDB;persist security info=True;user
id=xxxx;password=xxx;MultipleActiveResultSets=True;App=EntityFramework
- 设置完成后,您需要在应用程序中读取 url 并提供 DBContext。 DbContext 实现了一个带有连接字符串参数的构造函数。默认情况下,构造函数没有任何参数,但您可以扩展它。如果您使用的是 POCO classes,您可以简单地修改 DbContext class。如果你像我一样使用数据库生成的 Edmx classes,你不想接触自动生成的 edmx classes,而是想在同一个命名空间中创建部分 class 并且class 扩展如下。
这是自动生成的 DbContext
namespace myApp.Data.Models
{
public partial class myDBEntities : DbContext
{
public myDBEntities()
: base("name=myDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
}
这是新的部分class,您创建
namespace myApp.Data.Models
{
[DbConfigurationType(typeof(myDBContextConfig))]
partial class myDBEntities
{
public myDBEntities(string connectionString) : base(connectionString)
{
}
}
public class myDBContextConfig : DbConfiguration
{
public myDBContextConfig()
{
SetProviderServices("System.Data.EntityClient",
SqlProviderServices.Instance);
SetDefaultConnectionFactory(new SqlConnectionFactory());
}
}
}
- 毕竟你可以从 Azure 设置中获取连接字符串,在你的 Azure Function 项目中使用下面的代码并提供给你的 DbContext
myDBEntities 是您在 Azure 门户中为连接字符串提供的名称。
var connString = ConfigurationManager.ConnectionStrings["myDBEntities"].ConnectionString;
using (var dbContext = new myDBEntities(connString))
{
//TODO:
}
Configuration Manager 将被 Functions Runtime v2 中新的 Asp.Net Core Configuration System 取代。
因此,如果您使用的是 .Net Core,则应遵循 John Gallants 博客文章:
https://blog.jongallant.com/2018/01/azure-function-config/
- 使用 local.settings.json 和 Azure 函数中的设置
- 使用应用程序设置和连接字符串
Todd De Land 的回答仅适用于本地环境。但是,根据此 doc,已发布的 Azure 函数需要将连接字符串存储为应用程序设置并由 GetEnvironmentVariable
检索。
添加 System.Configuration
程序集引用 没有必要。
string cs = Environment.GetEnvironmentVariable("MyConnectionString",EnvironmentVariableTarget.Process);
以下是使本地和发布环境
均可检索环境字符串的步骤
- 要支持本地环境,请在
local.settings.json
中指定 Values
节点内的连接字符串
- 要支持已发布的环境,请转至
portal.azure.com > your Azure Function > function node > Application Settings
- 最后,从您的 Azure 函数调用
GetEnvironmentVariable
(无法让 Whosebug 正确显示此代码)
就是这样。
下面在本地和 Azure 中为我工作,用于查询 cosmos db 的 http 触发函数
向项目添加了Microsoft.Azure.WebJobs.Extensions.CosmosDB nuget 包引用
连接字符串设置:
local.settings.json
{
"ConnectionStrings": {
"CosmosDBConnection": "AccountEndpoint=foobar;"
}
}
在 Azure 门户 > 功能应用程序 > 平台功能 > 配置 > 应用程序设置 > 新应用程序设置 >
Name: CosmosDBConnection
Value: AccountEndpoint=foobar;
更新 > 保存
示例 c# Azure 函数
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
[CosmosDB(databaseName:"dbName",
collectionName:"collectionName",
ConnectionStringSetting = "CosmosDBConnection")] DocumentClient documentClient,
ILogger log){
.....
}
您应该将连接字符串存储在 azure key vault 中并在 azure 函数上启用 MSI 并在 azure key vault 上添加访问策略以读取密钥值。
我在我的本地数据库上尝试了下面的代码片段,这看起来很简单。一起来看看吧
Nuget 扩展:
从 Nuget Package Manager
在您的项目 Dependencies
部分
下载以下参考资料
using System.Data.SqlClient;
local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"sqldb_connection": "Data Source=.;Initial Catalog=DatabaseName;Connection Timeout=30;Integrated Security=True;"
}
}
读取函数体上的连接:
//读取数据库连接
var sqlConnection = Environment.GetEnvironmentVariable("sqldb_connection");
使用连接字符串的函数读写操作:
// Convert all request perameter into Json object
var content = req.Content;
string jsonContent = content.ReadAsStringAsync().Result;
dynamic requestPram = JsonConvert.DeserializeObject<AzureSqlTableClass>(jsonContent);
// Validate required param
if (string.IsNullOrEmpty(requestPram.FirstName))
{
return req.CreateResponse(HttpStatusCode.OK, "Please enter First Name!");
}
if (string.IsNullOrEmpty(requestPram.LastName))
{
return req.CreateResponse(HttpStatusCode.OK, "Please enter Last Name!");
}
//Read database Connection
var sqlConnection = Environment.GetEnvironmentVariable("sqldb_connection");
var responseResults = 0;
//Read Write Uisng Connection String
using (SqlConnection conn = new SqlConnection(sqlConnection))
{
conn.Open();
var text = "INSERT INTO AzureSqlTable VALUES ('" + requestPram.FirstName + "', '" + requestPram.LastName + "', '" + requestPram.Email + "') ";
using (SqlCommand cmd = new SqlCommand(text, conn))
{
responseResults = await cmd.ExecuteNonQueryAsync();
}
conn.Close();
}
return req.CreateResponse(HttpStatusCode.OK, responseResults);
Note: While publish your function on azure portal
just replace the connection string on local.settings.json
file. It will work
accordingly. See the screen shot below:
试试这个方法。
public static string GetConnectionString(string name)
{
string conStr = System.Environment.GetEnvironmentVariable($"ConnectionStrings:{name}",
EnvironmentVariableTarget.Process);
// Azure Functions App Service naming
if (string.IsNullOrEmpty(conStr))convention
conStr = System.Environment.GetEnvironmentVariable($"SQLAZURECONNSTR_{name}",
EnvironmentVariableTarget.Process);
return conStr;
}
上面的一些建议有效。然而,有一种更直接的方法来设置连接字符串。这是通过使用点击发布设置后看到的 'publish' 屏幕。 see picture from documentation here
处理连接字符串的最佳方法是使用 "Azure Key Vault"。您可以将所有重要机密存储在 Key Vault 中并在应用程序中使用。
根据其他成员的建议,您可以使用应用程序设置。
帮助完整链接:https://docs.microsoft.com/en-us/azure-stack/user/azure-stack-key-vault-manage-portal?view=azs-2002
https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-3.1
@ToddDeLand 的回答补充。
像这样的local.settings.json
:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": ""
},
"ConnectionStrings": {
"MyConnectionString": "[YourConnectionStringHere]"
}
}
然后您可以像这样访问您的连接字符串,不需要 NuGet。
var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings:MyConnectionString");
微软在这里推荐这种方法:
如果将连接字符串添加到值:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": "",
"MyConnectionString": "[YourConnectionStringHere]"
}
}
您可以像这样访问您的连接字符串:
var connectionString = Environment.GetEnvironmentVariable("MyConnectionString");
来源:
https://github.com/Azure/Azure-Functions/issues/717#issuecomment-400098791
如果您使用的是函数运行时 v3,则以下方法适合您。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": ""
},
"ConnectionStrings": {
"MyConnectionString": "[YourConnectionStringHere]"
}
}
在你函数的启动文件中
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
var config = builder.ConfigurationBuilder.Build();
var connectionString = config.GetConnectionString("MyConnectionString");
}
如何在 Azure 函数中添加或访问 app.config
文件以添加数据库连接字符串?
如果您不应该添加 app.config
并且有更好的方法访问外部数据库来执行函数,请告诉我最佳做法。谢谢!
执行此操作的最佳方法是从 Azure 门户添加连接字符串:
- 从您的函数应用程序 UI,单击函数应用程序设置
- 设置/应用设置
- 添加连接字符串
然后它们将使用与在 web.config 中相同的逻辑可用,例如
var conn = System.Configuration.ConfigurationManager
.ConnectionStrings["MyConn"].ConnectionString;
或者,如果您使用的是非 .NET 语言,则可以改用应用程序设置,它会在运行时成为您的函数可以访问的简单环境变量。
我相信常见的做法是为 azure 函数使用环境变量,然后您可以在 Azure 函数中设置环境变量:
(功能应用设置 -> 配置应用设置 -> 应用设置部分)
如果您也可以让我们知道您使用的是哪种语言,也许会更有帮助?
Jan_V 几乎 成功了,这促使我在 local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": ""
},
"ConnectionStrings": {
"MyConnectionString": "[YourConnectionStringHere]"
}
}
这允许您使用我们都习惯的ConfigurationManager.ConnectionStrings[]
。
var sqlConnection = ConfigurationManager
.ConnectionStrings["MyConnectionString"].ConnectionString;
我在这里经历了几个类似的问题和答案。他们中的许多人要么具有误导性,要么假设每个人都处于同一水平并且理解 azure 函数是如何工作的。像我这样的新手没有答案。我想在这里逐步总结我的解决方案。
最重要的是我们了解local.settings.json文件 不适合 AZURE。 运行 你的应用在本地就像名字一样 明明说所以解决方案与这个文件无关。
App.Config 或 Web.Config 不适用于 Azure 函数连接字符串。如果您有数据库层库,则无法像在 Asp.Net 应用程序中那样使用其中任何一个覆盖连接字符串。
为了使用,您需要在 Azure 函数的
Application Settings
下的 Azure 门户上定义连接字符串。有 连接字符串。在那里你应该复制你的 DBContext 的连接字符串。如果是 edmx,它将如下所示。有连接类型,我使用它 SQlAzure 但我测试了自定义(有人声称只适用于自定义)适用于两者。
metadata=res:///Models.myDB.csdl|res:///Models.myDB.ssdl|res://*/Models.myDB.msl;provider=System.Data.SqlClient;provider connection string='data source=[yourdbURL];initial catalog=myDB;persist security info=True;user id=xxxx;password=xxx;MultipleActiveResultSets=True;App=EntityFramework
- 设置完成后,您需要在应用程序中读取 url 并提供 DBContext。 DbContext 实现了一个带有连接字符串参数的构造函数。默认情况下,构造函数没有任何参数,但您可以扩展它。如果您使用的是 POCO classes,您可以简单地修改 DbContext class。如果你像我一样使用数据库生成的 Edmx classes,你不想接触自动生成的 edmx classes,而是想在同一个命名空间中创建部分 class 并且class 扩展如下。
这是自动生成的 DbContext
namespace myApp.Data.Models
{
public partial class myDBEntities : DbContext
{
public myDBEntities()
: base("name=myDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
}
这是新的部分class,您创建
namespace myApp.Data.Models
{
[DbConfigurationType(typeof(myDBContextConfig))]
partial class myDBEntities
{
public myDBEntities(string connectionString) : base(connectionString)
{
}
}
public class myDBContextConfig : DbConfiguration
{
public myDBContextConfig()
{
SetProviderServices("System.Data.EntityClient",
SqlProviderServices.Instance);
SetDefaultConnectionFactory(new SqlConnectionFactory());
}
}
}
- 毕竟你可以从 Azure 设置中获取连接字符串,在你的 Azure Function 项目中使用下面的代码并提供给你的 DbContext myDBEntities 是您在 Azure 门户中为连接字符串提供的名称。
var connString = ConfigurationManager.ConnectionStrings["myDBEntities"].ConnectionString; using (var dbContext = new myDBEntities(connString)) { //TODO: }
Configuration Manager 将被 Functions Runtime v2 中新的 Asp.Net Core Configuration System 取代。
因此,如果您使用的是 .Net Core,则应遵循 John Gallants 博客文章: https://blog.jongallant.com/2018/01/azure-function-config/
- 使用 local.settings.json 和 Azure 函数中的设置
- 使用应用程序设置和连接字符串
Todd De Land 的回答仅适用于本地环境。但是,根据此 doc,已发布的 Azure 函数需要将连接字符串存储为应用程序设置并由 GetEnvironmentVariable
检索。
添加 System.Configuration
程序集引用 没有必要。
string cs = Environment.GetEnvironmentVariable("MyConnectionString",EnvironmentVariableTarget.Process);
以下是使本地和发布环境
均可检索环境字符串的步骤- 要支持本地环境,请在
local.settings.json
中指定Values
节点内的连接字符串
- 要支持已发布的环境,请转至
portal.azure.com > your Azure Function > function node > Application Settings
- 最后,从您的 Azure 函数调用
GetEnvironmentVariable
(无法让 Whosebug 正确显示此代码)
就是这样。
下面在本地和 Azure 中为我工作,用于查询 cosmos db 的 http 触发函数
向项目添加了Microsoft.Azure.WebJobs.Extensions.CosmosDB nuget 包引用
连接字符串设置:
local.settings.json
{
"ConnectionStrings": {
"CosmosDBConnection": "AccountEndpoint=foobar;"
}
}
在 Azure 门户 > 功能应用程序 > 平台功能 > 配置 > 应用程序设置 > 新应用程序设置 >
Name: CosmosDBConnection
Value: AccountEndpoint=foobar;
更新 > 保存
示例 c# Azure 函数
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
[CosmosDB(databaseName:"dbName",
collectionName:"collectionName",
ConnectionStringSetting = "CosmosDBConnection")] DocumentClient documentClient,
ILogger log){
.....
}
您应该将连接字符串存储在 azure key vault 中并在 azure 函数上启用 MSI 并在 azure key vault 上添加访问策略以读取密钥值。
我在我的本地数据库上尝试了下面的代码片段,这看起来很简单。一起来看看吧
Nuget 扩展:
从 Nuget Package Manager
在您的项目 Dependencies
部分
using System.Data.SqlClient;
local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"sqldb_connection": "Data Source=.;Initial Catalog=DatabaseName;Connection Timeout=30;Integrated Security=True;"
}
}
读取函数体上的连接:
//读取数据库连接
var sqlConnection = Environment.GetEnvironmentVariable("sqldb_connection");
使用连接字符串的函数读写操作:
// Convert all request perameter into Json object
var content = req.Content;
string jsonContent = content.ReadAsStringAsync().Result;
dynamic requestPram = JsonConvert.DeserializeObject<AzureSqlTableClass>(jsonContent);
// Validate required param
if (string.IsNullOrEmpty(requestPram.FirstName))
{
return req.CreateResponse(HttpStatusCode.OK, "Please enter First Name!");
}
if (string.IsNullOrEmpty(requestPram.LastName))
{
return req.CreateResponse(HttpStatusCode.OK, "Please enter Last Name!");
}
//Read database Connection
var sqlConnection = Environment.GetEnvironmentVariable("sqldb_connection");
var responseResults = 0;
//Read Write Uisng Connection String
using (SqlConnection conn = new SqlConnection(sqlConnection))
{
conn.Open();
var text = "INSERT INTO AzureSqlTable VALUES ('" + requestPram.FirstName + "', '" + requestPram.LastName + "', '" + requestPram.Email + "') ";
using (SqlCommand cmd = new SqlCommand(text, conn))
{
responseResults = await cmd.ExecuteNonQueryAsync();
}
conn.Close();
}
return req.CreateResponse(HttpStatusCode.OK, responseResults);
Note: While publish your function on
azure portal
just replace the connection string onlocal.settings.json
file. It will work accordingly. See the screen shot below:
试试这个方法。
public static string GetConnectionString(string name)
{
string conStr = System.Environment.GetEnvironmentVariable($"ConnectionStrings:{name}",
EnvironmentVariableTarget.Process);
// Azure Functions App Service naming
if (string.IsNullOrEmpty(conStr))convention
conStr = System.Environment.GetEnvironmentVariable($"SQLAZURECONNSTR_{name}",
EnvironmentVariableTarget.Process);
return conStr;
}
上面的一些建议有效。然而,有一种更直接的方法来设置连接字符串。这是通过使用点击发布设置后看到的 'publish' 屏幕。 see picture from documentation here
处理连接字符串的最佳方法是使用 "Azure Key Vault"。您可以将所有重要机密存储在 Key Vault 中并在应用程序中使用。 根据其他成员的建议,您可以使用应用程序设置。
帮助完整链接:https://docs.microsoft.com/en-us/azure-stack/user/azure-stack-key-vault-manage-portal?view=azs-2002
https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-3.1
@ToddDeLand 的回答补充。
像这样的local.settings.json
:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": ""
},
"ConnectionStrings": {
"MyConnectionString": "[YourConnectionStringHere]"
}
}
然后您可以像这样访问您的连接字符串,不需要 NuGet。
var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings:MyConnectionString");
微软在这里推荐这种方法:
如果将连接字符串添加到值:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": "",
"MyConnectionString": "[YourConnectionStringHere]"
}
}
您可以像这样访问您的连接字符串:
var connectionString = Environment.GetEnvironmentVariable("MyConnectionString");
来源:
https://github.com/Azure/Azure-Functions/issues/717#issuecomment-400098791
如果您使用的是函数运行时 v3,则以下方法适合您。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true;",
"AzureWebJobsDashboard": ""
},
"ConnectionStrings": {
"MyConnectionString": "[YourConnectionStringHere]"
}
}
在你函数的启动文件中
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
var config = builder.ConfigurationBuilder.Build();
var connectionString = config.GetConnectionString("MyConnectionString");
}