Shaun Luttin
Shaun Luttin

Reputation: 141462

Access connection strings in ASP.NET 5 on Azure

In ASP.NET 5, how do we programmatically access an Azure Web App's connection strings? I've been able to retrieve the TEST_APP_SETTINGS value but not the TestConnString one.

App Settings and Connection Strings

Here is what I have tried:

services.Configure<AppSettings>(Configuration.GetSubKey("AppSettings"));

I'm afraid that AppSettings doesn't exist. I've also done this and the app settings show up but the connection strings do not.

Startup.cs

// Setup configuration sources.
Configuration = new Configuration()
    .AddJsonFile("config.json")
    .AddEnvironmentVariables();

// Allow access from *.cshtml
services.AddSingleton<Configuration>(provider => 
{ 
    return Configuration as Configuration; 
});

Dev.cshtml

@inject Microsoft.Framework.ConfigurationModel.Configuration config;

<dl>
    @foreach(var k in @config.GetSubKeys())
    {
        <dt>@k.Key</dt>
        <dd>@config.Get(k.Key)</dd>
    }
</dl>

Upvotes: 3

Views: 626

Answers (3)

Nick Miller
Nick Miller

Reputation: 602

I found the following way simplest. It does remove the risk of putting the connection string in source control. I'm not sure how it rates security-wise compared to setting an environment variable.

  1. In the Azure Portal, set ASPNET_Env environment variable for the website to 'Production'.
  2. Secure FTP to the website using the FTP address shown in the Azure Portal. Note the Azure Portal has a secure FTP and a non-secure FTP end point. Be sure to use the secure one. (You may need to 'reset deployment credentials' via the Azure Portal to set an FTP password.)
  3. Find where the appsettings.json file: 'approot/src/'. Copy it to 'appsettings.Production.json'.
  4. In 'appsettings.Production.json', change the connection string to the connection string for the production database.
  5. In the Startup class in your ASP.NET 5 project:
var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true);

Upvotes: 0

Rick Love
Rick Love

Reputation: 12780

This is an extension of Victor's answer that helped me understand what was happening in the new MVC 6 environment.

In the config.json file I have this:

"Data": {
    "DefaultConnection": {
        "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-TestWepApp-e35abc53-9a43-4b2b-886d-d8582c0a1ccd;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
},

This is the DefaultConnection which is used whenever my DBContext uses the empty constructor.

Now, the Azure Connection String maps to Data:NAME:ConnectionString. So we see a correspondence.

All that is needed is to name the Azure Connection String "DefaultConnection" and ensure environment variables are included in the configuration (which it is by default) and everything works as expected.

configuration.AddJsonFile("config.json")
// ...
configuration.AddEnvironmentVariables()

So when the configuration is loaded, the config.json value for Data:DefaultConnection:ConnectionString will be replaced by the environment variable set by Azure because AddEnvironmentVariables is called after the config.json is loaded into the configuration.

Update

After using the OP's script to view the Debug values, I don't see the connection string listed.

The issue is that the keys are hierarchical. Here is the updated code that should show all keys:

@*
    For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
// ViewBag.Title = "Home Page";
}

@inject Microsoft.Framework.ConfigurationModel.Configuration config;

@functions{

    public IEnumerable<string> GetAllKeys()
    {
        var keys = new List<string>();

        foreach (var k in config.GetSubKeys())
        {
            GetAllKeys(keys, k.Key);
        }

        return keys;
    }

    public void GetAllKeys(List<string> keys, string key)
    {
        keys.Add(key);

        foreach (var k in config.GetSubKeys(key))
        {
            GetAllKeys(keys, key + ":" + k.Key);
        }
    }
}

<dl>
    @foreach (var key in GetAllKeys())
    {
        <dt>@key</dt>
        <dd>@config.Get(key)</dd>
    }
</dl>

Upvotes: 0

Victor Hurdugaci
Victor Hurdugaci

Reputation: 28425

The connection strings are set as environment variables. Therefore, first you have to add the environment variable configuration source and then the connection strings will be named Data:NAME:ConnectionString where NAME is the name of the connection string in the portal.

For example, if your connection string is "ServerConnection" then you access it using using Data:ServerConnection:ConnectionString

Here are the tests that validate the mapping environment configuration mappings, they might explain it better.

Upvotes: 3

Related Questions