2

I have the following local.settings.json file:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureWebJobsDashboard": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",

    "SureMdmApiKey": "xxx",
    "SureMdmApiUrl": "xxx",
    "SureMdmUsername": "xxx",
    "SureMdmPassword": "xxx"
  },
  "ConnectionStrings": {
    "StorageConnectionString": "aaaa",
    "DataContext": "aaaa"
  }
}

then I have the following code in Startup.cs file:

[assembly: FunctionsStartup(typeof(FunctionAppSureMdmSync.Startup))]
namespace FunctionAppSureMdmSync
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var services = builder.Services;

            services.AddTransient<ISureMdmService>(s => new SureMdmService(
                url: System.Environment.GetEnvironmentVariable("SureMdmApiUrl"),
                username: System.Environment.GetEnvironmentVariable("SureMdmUserName"),
                password: System.Environment.GetEnvironmentVariable("SureMdmPassword"),
                apiKey: System.Environment.GetEnvironmentVariable("SureMdmApiKey")
                ));

            var connString = System.Environment.GetEnvironmentVariable("ConnectionStrings:DataContext");
            services.AddDbContext<DataContext>(options => options
                .UseSqlServer(connString, x => x.UseNetTopologySuite()));


            services.AddTransient<ITabletGroupService, TabletGroupService>();
            services.AddTransient<ITabletService, TabletService>();
        }

    }
}

and it works fine on local

But when I publish this function to Azure Portal and go to "Configuration" and add "DataContext" to "Connection Strings":

enter image description here

My code does not work:

            var connString = System.Environment.GetEnvironmentVariable("ConnectionStrings:DataContext");

How to get connection string? I want that it works both, on local and Portal Azure?

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159

3 Answers3

8

I’ve found that to access IConfiguration in Startup, you need to build a temporary service provider, that you just throw away. There might be better ways more recently, but it still works fine:

var configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>(); 

Then, don’t use System.Environment.GetEnvironmentVariable(), but IConfiguration instead (same applies for all your configuration):

var connString = configuration.GetConnectionString("DataContext");
sellotape
  • 8,034
  • 2
  • 26
  • 30
  • 1
    is `builder.GetContext().Configuration.GetConnectionString("DataContext")` the "better more recent way" you're referring to? – Chris DaMour Jun 16 '22 at 23:36
0

You need to add the variable in the Configuration as ConnectionStrings:DataContext.

Raffy
  • 515
  • 1
  • 8
  • 12
0

The way I do to connect to a SQL server on my azure functions is like this:

var config = new ConfigurationBuilder()
           .SetBasePath(context.FunctionAppDirectory)
           .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
           .AddEnvironmentVariables()
           .Build();

var str = config.GetConnectionString("DataContext");

In the function parameters:

public static void Run( blablabla,
            ExecutionContext context
            )
Carlos Alves Jorge
  • 1,919
  • 1
  • 13
  • 29
  • 1
    The V2 Functions runtime already does that for you, and you can just [inject an `IConfiguration`](https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#function-app-provided-services) and use it. – sellotape Mar 21 '20 at 21:59
  • but Portal Azure Function does not have `local.settings.json` file – Oleg Sh Mar 22 '20 at 19:03
  • @OlegSh - when you run the function locally, the host automatically loads your settings from local.settings.json into the `IConfiguration`. When the same function is hosted in Azure it automatically loads settings from your App Settings as configured in Azure instead. – sellotape Mar 22 '20 at 20:44