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 函数是如何工作的。像我这样的新手没有答案。我想在这里逐步总结我的解决方案。

  1. 最重要的是我们了解local.settings.json文件 不适合 AZURE。 运行 你的应用在本地就像名字一样 明明说所以解决方案与这个文件无关。

  2. App.Config 或 Web.Config 不适用于 Azure 函数连接字符串。如果您有数据库层库,则无法像在 Asp.Net 应用程序中那样使用其中任何一个覆盖连接字符串。

  3. 为了使用,您需要在 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

  1. 设置完成后,您需要在应用程序中读取 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());
            }
        }
    }
  1. 毕竟你可以从 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);

以下是使本地和发布环境

均可检索环境字符串的步骤
  1. 要支持本地环境,请在 local.settings.json 中指定 Values 节点内的连接字符串

  1. 要支持已发布的环境,请转至 portal.azure.com > your Azure Function > function node > Application Settings

  1. 最后,从您的 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");

微软在这里推荐这种方法:

https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#environment-variables

如果将连接字符串添加到值:

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