182

I want to read just a connection string from a configuration file and for this add a file with the name "appsettings.json" to my project and add this content on it:

{
"ConnectionStrings": {
  "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-

 WebApplica71d622;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
    "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
    "Default": "Debug",
    "System": "Information",
    "Microsoft": "Information"
   }
 }
}

On ASP.NET I used this:

 var temp=ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

Now how can I read "DefaultConnection" in C# and store it on a string variable in .NET Core?

1

16 Answers 16

150

The posted answer is fine but didn't directly answer the same question I had about reading in a connection string. Through much searching I found a slightly simpler way of doing this.

In Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...
    // Add the whole configuration object here.
    services.AddSingleton<IConfiguration>(Configuration);
}

In your controller add a field for the configuration and a parameter for it on a constructor

private readonly IConfiguration configuration;

public HomeController(IConfiguration config) 
{
    configuration = config;
}

Now later in your view code you can access it like:

connectionString = configuration.GetConnectionString("DefaultConnection");
Sign up to request clarification or add additional context in comments.

12 Comments

Wouldn't do it like that. If you work without entity framework, you better register a connection factory as singleton, e.g. to use with dapper. You can then still expose a connectionString property if you need to, but I bet it wouldn't be necessary in 99% of cases.
But how to access Configuration in Models instead of Controller?
The more I read and try things, the more I realize getting a connection string is a major undertaking. I just get nulls no matter what I try.
Yeah. Too many computer scientists creating huge high hanging fruit just to say "Hello World". Unbelievable. Entropy at it's best.
I agree with @JustJohn, this is unnecessary over-engineering at its finest. Connection strings should be easily available and shouldn't take several hours to implement. There is no need to make everything abstract and wrapped in factories and god knows what else. Some things should always stay simple.
|
123

You can do this with the GetConnectionString extension-method:

string conString = Microsoft
   .Extensions
   .Configuration
   .ConfigurationExtensions
   .GetConnectionString(this.Configuration, "DefaultConnection");

System.Console.WriteLine(conString);

or with a structured-class for DI:

public class SmtpConfig
{
    public string Server { get; set; }
    public string User { get; set; }
    public string Pass { get; set; }
    public int Port { get; set; }
}

Startup:

public IConfigurationRoot Configuration { get; }


// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // http://developer.telerik.com/featured/new-configuration-model-asp-net-core/
    // services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));
    Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure<SmtpConfig>(services, Configuration.GetSection("Smtp"));

And then in the home-controller:

public class HomeController : Controller
{

    public SmtpConfig SmtpConfig { get; }
    public HomeController(Microsoft.Extensions.Options.IOptions<SmtpConfig> smtpConfig)
    {
        SmtpConfig = smtpConfig.Value;
    } //Action Controller


    public IActionResult Index()
    {
        System.Console.WriteLine(SmtpConfig);
        return View();
    }

with this in appsettings.json:

"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-WebApplica71d622;Trusted_Connection=True;MultipleActiveResultSets=true"
},

"Smtp": {
    "Server": "0.0.0.1",
    "User": "[email protected]",
    "Pass": "123456789",
    "Port": "25"
  }

15 Comments

Configure is an extension method. It should be used most commonly like this: services.Configure<SmtpConfig>(Configuration.GetSection("Smtp")); Sure, it's much the same thing, but I think people not aware will just start doing it the "wrong" way, using the uncommented line, so perhaps best to remove the line. ;)
@JedatKinports: No, only injection. Even if you'd write a static method, you'd still need the configuration. You could just read a JSON/YAML file manually, though. But that will eliminate overwrites, such as usersecrets or others (e.g. configuration from registry).
I am getting an error: "MyClass does contain a definition for 'Configuration'..."
What is "this.Configuration" referring to in the connection string part? GetConnectionString(this.Configuration, "DefaultConnection")
Amazing. And for ConnectionString, which is the question about, how to do it?
|
36

In .NET Core 6

appsettings.json

 "ConnectionStrings": {
   "DefaultConnection": "Server=**Server Name**;Database=**DB NAME**;Trusted_Connection=True;MultipleActiveResultSets=true"
  }

Program.cs

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));

DB Context

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {

    }

}

2 Comments

Thanks for clarifying, this is so vital - builder.Configuration.GetConnectionString("DefaultConnection"); it is indeed different in .Net 6 sdk.
I recommend against MARS (multiple active result sets) because this can cause many round-trips to the database, which can be a difficult-to-diagnose performance issue.
27

See link for more info: https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-strings

JSON

    {
      "ConnectionStrings": {
        "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
      },
    }

C# Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<BloggingContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
}

EDIT: aspnetcore, starting 3.1: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

4 Comments

Why should JSON file should have ConnectionStrings instead of ConnectionString ? Because when I used ConnectionString, then we I'm getting null.
@Vijay Try using the prescribed method then ;) Please see the attached link.
This method seems out of date as of Microsoft.Extensions.Configuration (3.1.5)
@Ju66ernaut I believe my edit should bring the answer back to being relevant
14

This is how I did it:

I added the connection string at appsettings.json

"ConnectionStrings": {
"conStr": "Server=MYSERVER;Database=MYDB;Trusted_Connection=True;MultipleActiveResultSets=true"},

I created a class called SqlHelper

public class SqlHelper
{
    //this field gets initialized at Startup.cs
    public static string conStr;

    public static SqlConnection GetConnection()
    {
        try
        {
            SqlConnection connection = new SqlConnection(conStr);
            return connection;
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}

At the Startup.cs I used ConfigurationExtensions.GetConnectionString to get the connection,and I assigned it to SqlHelper.conStr

public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        SqlHelper.connectionString = ConfigurationExtensions.GetConnectionString(this.Configuration, "conStr");
    }

Now wherever you need the connection string you just call it like this:

SqlHelper.GetConnection();

3 Comments

Where is 'connectionString' defined? SqlHelper.connectionString?
@Nathan it looks like he renamed it from conStr to connectionString as he mentions both interchangeably.
Neat and clearly explained
9

The way that I found to resolve this was to use AddJsonFile in a builder at Startup (which allows it to find the configuration stored in the appsettings.json file) and then use that to set a private _config variable

public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        _config = builder.Build();
    }

And then I could set the configuration string as follows:

var connectionString = _config.GetConnectionString("DbContextSettings:ConnectionString"); 

This is on dotnet core 1.1

2 Comments

how can i access _config in my control?
By adding it to the DI container in ConfigureServices in Startup.cs.
8

ASP.NET Core (in my case 3.1) provides us with Constructor injections into Controllers, so you may simply add following constructor:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    private readonly IConfiguration m_config;

    public TestController(IConfiguration config)
    {
        m_config = config;
    }

    [HttpGet]
    public string Get()
    {
        //you can get connection string as follows
        string connectionString = m_config.GetConnectionString("Default")
    }
}

Here what appsettings.json may look like:

{
    "ConnectionStrings": {
        "Default": "YOUR_CONNECTION_STRING"
        }
}

Comments

4

The method below will work fine if you want to get a connectionString from appsettings.json into a Model or ViewModel (not Controller). This is for ASP.NET Core 3 and above. Sometimes you may need to get a connectionString into a Model (for SQL queries) rather than dependency injection via the controller so this method below will get your connectionString from appsettings:

public class NameOfYourModel
{
  static class getConnection
  {
    public static IConfigurationRoot Configuration;
    public static string GetConnectionString()
    {
      var builder = new ConfigurationBuilder()
      .SetBasePath(System.IO.Directory.GetCurrentDirectory())
      .AddJsonFile("appsettings.json");
       Configuration = builder.Build();
       var connectionString =   
    Configuration.GetConnectionString("connectionStringName");
       
       return connectionString;
     }
    }
    string connStr = getConnection.GetConnectionString().ToString(); //This   
   //line now has your connectionString which you can use. 

 //Continue the rest of your code here.
}

Comments

3

In 3.1 there is a section already defined for "ConnectionStrings"

System.Configuration.ConnnectionStringSettings

Define:

  "ConnectionStrings": {
    "ConnectionString": "..."
  }

Register:

public void ConfigureServices(IServiceCollection services)
{
     services.Configure<ConnectionStringSettings>(Configuration.GetSection("ConnectionStrings"));
}

Inject:

public class ObjectModelContext : DbContext, IObjectModelContext
{

     private readonly ConnectionStringSettings ConnectionStringSettings;

    ...

     public ObjectModelContext(DbContextOptions<ObjectModelContext> options, IOptions<ConnectionStringSettings> setting) : base(options)
    {
          ConnectionStringSettings = setting.Value;
    }

    ...
}

Use:

   public static void ConfigureContext(DbContextOptionsBuilder optionsBuilder, ConnectionStringSettings connectionStringSettings)
    {
        if (optionsBuilder.IsConfigured == false)
        {
            optionsBuilder.UseLazyLoadingProxies()
                          .UseSqlServer(connectionStringSettings.ConnectionString);
        }
    }

Comments

3

This answer is similar to other but a little more straight forward.
Tested in .NET Core 6.
Assuming connection string in appsettings.json like this.

"ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\xxx"
    "Connect_2": "Data Source=((SERVICE_NAMEXXX"
}

var builder = new ConfigurationBuilder();

builder.AddJsonFile("appsettings.json");

IConfiguration configuration = builder.Build();
string _connstr = configuration.GetConnectionString("DefaultConnection");
string _connstr2 = configuration.GetConnectionString("Connect_2");`

_connstr will hold "Server=(localdb)\xxx".
_connstr2 will hold "Data Source=((SERVICE_NAMEXXX".

1 Comment

I think this is the simple and straightforward way for reading a config in .Net Core. Lot of various options are listed and explained at code-maze.com/dotnet-read-connection-strings including usage of ConfigurationBuilder() class
2

There is another approach. In my example you see some business logic in repository class that I use with dependency injection in ASP .NET MVC Core 3.1.

And here I want to get connectiongString for that business logic because probably another repository will have access to another database at all.

This pattern allows you in the same business logic repository have access to different databases.

C#

public interface IStatsRepository
{
            IEnumerable<FederalDistrict> FederalDistricts();
}

class StatsRepository : IStatsRepository
{
   private readonly DbContextOptionsBuilder<EFCoreTestContext>
                optionsBuilder = new DbContextOptionsBuilder<EFCoreTestContext>();
   private readonly IConfigurationRoot configurationRoot;

   public StatsRepository()
   {
       IConfigurationBuilder configurationBuilder = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
           .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
       configurationRoot = configurationBuilder.Build();
   }

   public IEnumerable<FederalDistrict> FederalDistricts()
   {
        var conn = configurationRoot.GetConnectionString("EFCoreTestContext");
        optionsBuilder.UseSqlServer(conn);

        using (var ctx = new EFCoreTestContext(optionsBuilder.Options))
        { 
            return ctx.FederalDistricts.Include(x => x.FederalSubjects).ToList();
        }
    }
}

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "EFCoreTestContext": "Data Source=DESKTOP-GNJKL2V\\MSSQLSERVER2014;Database=Test;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Comments

1

Too late, but after reading all helpful answers and comments, I ended up using Microsoft.Extensions.Configuration.Binder extension package and play a little around to get rid of hardcoded configuration keys.

My solution:

IConfigSection.cs

public interface IConfigSection
{
}

ConfigurationExtensions.cs

public static class ConfigurationExtensions
{
    public static TConfigSection GetConfigSection<TConfigSection>(this IConfiguration configuration) where TConfigSection : IConfigSection, new()
    {
        var instance = new TConfigSection();
        var typeName = typeof(TConfigSection).Name;
        configuration.GetSection(typeName).Bind(instance);

        return instance;
    }
}

appsettings.json

{
   "AppConfigSection": {
      "IsLocal": true
   },
   "ConnectionStringsConfigSection": {
      "ServerConnectionString":"Server=.;Database=MyDb;Trusted_Connection=True;",
      "LocalConnectionString":"Data Source=MyDb.db",
   },
}

To access a strongly typed config, you just need to create a class for that, which implements IConfigSection interface(Note: class names and field names should exactly match section in appsettings.json)

AppConfigSection.cs

public class AppConfigSection: IConfigSection
{
    public bool IsLocal { get; set; }
}

ConnectionStringsConfigSection.cs

public class ConnectionStringsConfigSection : IConfigSection
{
    public string ServerConnectionString { get; set; }
    public string LocalConnectionString { get; set; }

    public ConnectionStringsConfigSection()
    {
        // set default values to avoid null reference if
        // section is not present in appsettings.json
        ServerConnectionString = string.Empty;
        LocalConnectionString = string.Empty;
    }
}

And finally, a usage example:

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // some stuff

        var app = Configuration.GetConfigSection<AppConfigSection>();
        var connectionStrings = Configuration.GetConfigSection<ConnectionStringsConfigSection>();

        services.AddDbContext<AppDbContext>(options =>
        {
            if (app.IsLocal)
            {
                options.UseSqlite(connectionStrings.LocalConnectionString);
            }
            else
            {
                options.UseSqlServer(connectionStrings.ServerConnectionString);
            }
        });

        // other stuff
    }
}

To make it neat, you can move above code into an extension method.

That's it, no hardcoded configuration keys.

Comments

1
private readonly IConfiguration configuration;
        public DepartmentController(IConfiguration _configuration)
        {
            configuration = _configuration;
        }

        [HttpGet]
        public JsonResult Get()
        {
string sqlDataSource = configuration["ConnectionStrings:DefaultConnection"];

Comments

0

A more handy explanation would be like below:

AppSettings.json:

"ConnectionStrings": {    
"MySQLConnection": "server=localhost; port=3306; database=xxxxx; user=root; password=******; Persist Security Info=False; Connect Timeout=300"
},

And in StartUp:

public class Startup {
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
    ........
    string mySqlConnection = Configuration.GetConnectionString("NameSetByYouInAppSettings");

Comments

-1

i have a data access library which works with both .net core and .net framework.

the trick was in .net core projects to keep the connection strings in a xml file named "app.config" (also for web projects), and mark it as 'copy to output directory',

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="conn1" connectionString="...." providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

ConfigurationManager.ConnectionStrings - will read the connection string.

    var conn1 = ConfigurationManager.ConnectionStrings["conn1"].ConnectionString;

1 Comment

If you're using .NET Core, it's best to adopt its configuration pattern instead of shoehorning in the .NET Framework pattern.
-3

You can use configuration extension method : getConnectionString ("DefaultConnection")

https://docs.asp.net/projects/api/en/latest/autoapi/Microsoft/Extensions/Configuration/ConfigurationExtensions/index.html#Microsoft.Extensions.Configuration.ConfigurationExtensions.GetConnectionString

1 Comment

The link appears to be dead

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.