Change connection string at runtime MySql C# - c#

i have an app.config file that has a connection string for my database.
what i want to do is to connect to different databases that's why i used to this code:
connectionString = "Data Source=blah;Initial Catalog=blah;UID=blah;password=blah";
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var connectionStringsSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
connectionStringsSection.ConnectionStrings[nameofConnectionString].ConnectionString = connectionString;
config.Save();
ConfigurationManager.RefreshSection(nameofConnectionString);
it works well, it changed the connection string, but the problem is that it sends me an error saying "facerec6.0.cdcol does not exist"
my default initial catalog = facerec6.0
what will i do ?

The ConnectionStringSection is just a container to store named connection strings. If you want to connect to different databases then it's best to start by storing those different connection strings in that section from the start and then determining how your application will choose which one to use at runtime.
Think of that section as just that and nothing more - it's a convenient, known place to store connection strings with a standard way to retrieve them. Other developers working on the code will know where to look for them and know how to retrieve them.
Even though it's technically possible to modify that section at runtime and save the file I wouldn't do that. If you have the same code that may use different connection strings while running in the same environment (it's not a case of one for development, one for QA, and one for production) then you could have your class depend on an interface something like this:
public interface IConnectionStringFactory
{
string GetConnectionString(Something key);
}
Where Something is a value that the class requiring the connection string can pass to the factory, and the factory can use it to determine which connection string to retrieve. That way the class that uses the connection string is insulated from that logic. It doesn't know why it uses one connection string or another. It just gets a connection string from the factory and then uses it.
If it's a case of varying connection strings by environment then that's much, much easier - you can do that with config transforms. In most cases if it's a different environment then all the connection strings will be different for each environment, so you can just replace the whole section.
<connectionStrings xdt:Transform="Replace">
<add name="connectionStringA" connectionString="...whatever..." />
</connectionStrings>

Please try this instead:
ConfigurationManager.RefreshSection("connectionStrings");
because:
<connectionStrings> <- this is the section
<add name="facerec6.0"/> <- this is the element
<add ... />
</connectionStrings>
You need to refresh the section, not the element, when using RefreshSection.

Related

Correctly storing db connection strings in environment variables ASP.Net MVC Apps

I am trying to move my 2 database connection strings to environment variables for security reasons. Everything works fine when I include the 2 connection strings on web.config like so:
<connectionStrings>
<clear />
<add name="DefaultConnection" connectionString="Data Source=xxxxxx" providerName="System.Data.SqlClient" />
<add name="RDSContext" connectionString="Data Source=xxxxxx" providerName="System.Data.SqlClient" />
</connectionStrings>
I then removed the 2 connection strings from web.config and created 2 environment variables as follows:
setx CUSTOMCONNSTR_DefaultConnection "Data Source=xxxxx"
setx CUSTOMCONNSTR_RDSContext "Data Source=xxxxx"
Although I now get the following error when I startup IIS and visit the web app
Server Error in '/' Application.
Cannot attach the file 'C:\Users\xxx\xxx\App_Data\BookingSystem.Models.RDSContext.mdf' as database 'BookingSystem.Models.RDSContext'.
Can anyone tell me what I am doing incorrect?
Simply naming your environment variable in a certain way doesn't mean that MVC will pick them up. You may be assuming a little more magic is happening than there actually is.
When you do ConfigurationManager.ConnectionStrings["MyConnectionStringName"].ConnectionString you're only retrieving the connection string from your web.config file, or machine.config if you happened to have defined it there. There's nothing there to tell your app to grab it from anywhere else.
Instead, you might consider creating a class to represent your configuration:
public class MyApplicationDatabaseConfiguration
{
public string ConnectionString { get; set; }
}
Any class that needs to obtain this connection string can do so by depending on an instance of that MyApplicationDatabaseConfiguration.
public class MyDatabaseRepository
{
readonly MyApplicationDatabaseConfiguration _dbConfig;
public MyDatabaseRepository(MyApplicationDatabaseConfiguration dbConfig)
{
_dbConfig = dbConfig;
}
public void DoSomethingWithTheDatabase()
{
using(var connection = new SqlConnection(_dbConfig.Connectionstring))
{
//now you can use the connection
}
}
}
Then you can load your config however you like. Ex:
MyApplicationDatabaseConfiguration dbConfig = new MyApplicationDatabaseConfiguration();
dbConfig.ConnectionString = Environment.GetEnvironmentVariable("MyApplication_MyConnectionString");
Now the MyDatabaseRepository doesn't care how you load the database config, it simply says "I need the database config". This is extremely powerful, it allows you to change out the configuration by simply changing a line of code. Need to change back to using web.config? It's as simple as dbConfig.ConnectionString = ConfigurationManager.ConnectionStrings["MyConnectionStringName"].ConnectionString;
Microsoft has taken this one step further in Microsoft.Extensions.Configuration library, which is meant for .NET Core but targeted to .NET Standard, so you can use it in your .NET Framework library if you'd like.

Entity Framework - Invalid Object with custom connections string

Just for a brief overview this is how I added the database into my project:
I have added a datasource by adding an ADO.NET Data Model Entity and selecting EF Designer from Database.
Doing so has generated a connection string for me in my web.config. Integrated Security is set to true (if that matters).
Once connected I right clicked and selected 'Update model from database.
Since there is multiple environments I built a custom context with a parametized constructor. Code looks as such (condensed and censored):
public partial class DataEntities : DbContext
{
public DataEntities(string connectionString)
: base(connectionString)
{
}
}
With each environment there are different local sql accounts associated. Requiring me to generate a connection string that is associated with the correct account in the correct environment. Doing so my web config looks something like this:
<connectionStrings>
<add name="DataEntities" connectionString="metadata=res://*/Models.XXModel.XXModel.csdl|res://*/Models.XXModel.XXModel.ssdl|res://*/Models.XXModel.XXModel.msl;provider=System.Data.SqlClient;provider connection string="data source=MYSQLSERVER;initial catalog=Data;integrated security=True;MultipleActiveResultSets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<secureConnectionStringsSection passwordPolicy="AllowLocalPasswordsForConnectionStrings">
<secureConnectionStrings>
<add name="DataEntities-Local" providerName="System.Data.SqlClient" connectionString="data source=MYSQLSERVER;user id=ACCNT; password=PASSWORD;" />
</secureConnectionStrings>
</secureConnectionStringsSection>
When I am instantiating my DataEntity object, I am calling a helper function I have written to get my custom connection string. I am doing so via the following code:
private DataEntities adDB = new DataEntities(XXX.Helpers.EFDBHelper.getDataConnectionString());
I can verify that my connection string helper does correctly pull the custom connection string that I have in my web.config. However once I actually try to make a call on the database I am left with the following error:
Invalid object name 'dbo.mycolumn'.
I know that my parametized constructor is being called with the correct connection string. I also know my connection string is valid, I have tested it in powershell:
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "data source=MYSQLSERVER;user id=ACCNT;password=PASSWORD"
$conn.Open()
$conn.Close()
I am certain that it is not an issue with the database itself as well. The moment I remove the parameter from my Entity initialization:
private DataEntities adDB = new DataEntities();
I am able to pull data from the database. I am assuming that it uses the auto-generated connection string. Which won't work since I cannot use integrated security once it goes past my local environment.
My apologies, I am new to the technology here. I am sure that it is just something small that I am missing.
In my connection string I did not specify a catalog.
Since I am newish to the technology, I tried to simply replicate some of the existing code that I had inherited. In the connection string I tried to replicate from, no catalog was expressed as well.
However... the account I am using to talk to the new datasource has access to all levels of the database so the catalog was required. The old inherited database had only one catalog the the sql account had access too.
You live and you learn!

Overwrite connection string stored in app.config in C# winforms

Hi I am developing an application for that I am taking connection string through dynamically from user at first time run.
My app.config is
<connectionStrings>
<add name="DConnection" connectionString=""
providerName="MySql.Data.MySqlClient"/>
<add name="SConnection" connectionString=""
providerName="System.Data.SqlClient" />
</connectionStrings>
I am assigning connection string to app.config's attributes by using below methods
private void CheckingSource(string constr)
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings["SConnection"].ConnectionString = constr; //CONCATINATE YOUR FIELDS TOGETHER HERE
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("connectionStrings");
}
private void CheckingDestination(string constr)
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings["DConnection"].ConnectionString = constr; //CONCATINATE YOUR FIELDS TOGETHER HERE
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("connectionStrings");
}
Now I have to write this connection string to app.config so when user run application next time these updated connection strings should be in use.
How can we manage it? I don't have any idea as I am still fresher to app.config and it's usage.
Now I have to write this connection string to app.config so when user run application next time these updated connection strings should be in use.
You shouldn't do this, the app.config file might be deployed to somewhere like C:\Program Files\Your Application which is not writeable by normal users.
Instead, supply the connection string to whatever needs it in some way other than using ConfigurationManager.ConnectionStrings.
using (var connection = new SqlConnection(GetConnectionStringFromUser())) { ...
With specific regards to "saving" a connection string, you should look at some sort of persistence mechanism like .NET's Application Settings.
The application settings architecture supports defining strongly typed settings with either application or user scope, and persisting the settings between application sessions.
Thanks #ta.speot.is resolved the issue using application setting.
Reference link.
Application Setting
might be helpful to all needy. Cheers.. :)

How to separate connection string and get connection string from a class in C#

I'm newbie in C#. I want to ask, how can I separate the connection string config into a class?
Because every time I want to write code, I need to re-write the connection string and test the connection. So, I need to make a class so that every time I make a connection to the database, this class will test the connection first. Then after it works, the class will send the connection string to my coding.
Besides, if I want to change my source data, I just need to change in the class only. No need to search all my coding
So if I can make a class, how do I call and get the connection string from class?
Can it be like that?
This is my current coding for connection string in C#
FileInfo file = new FileInfo(Application.StartupPath + "\\conn.txt");
if (file.Exists)
{
StreamReader r = File.OpenText(Application.StartupPath + "\\conn.txt");
connString = r.ReadToEnd();
r.Close();
// Open SQL connection
SqlConnection openCon = new SqlConnection(connString);
try
{
Cursor = Cursors.WaitCursor;
openCon.Open();
}
catch
{
MessageBox.Show("Error to established connection\nPlease check Data Source");
openCon.Close();
Cursor = Cursors.Arrow;
}
else
{
MessageBox.Show("File config is missing");
}
}
Hope you can teach me as a newbie in C#. Thanks for the help. And sorry for bad english.
You should store connection strings in your configuration file. If you don't have a configuration file, add one by right-clicking the project and 'adding new item...' If you are writing a web app it will be a web.config file; if you are writing a client app it will be an app.config file.
You add a connection string to the configuration file in the connectionStrings node, normally at the top of the file.
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<!-- add a string -->
<add name="MyConnectionString"
connectionString="Data Source=localhost; ... // etc
providerName="System.Data.SqlClient" />
</connectionStrings>
// and keep all the other configuration in the file
And then you simply refer to the configuration file using the ConfigurationManager class - you'll need to add a reference to System.Configuration if you don't already have one.
ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
You're trying to reinvent the wheel here. The .Net framework already include some simple techniques to handle this. If you're creating a Windows form project, you can store the connection string in App.Config using the connectionString attributes. If this is a web app, then you store it in web.config, here is how it would look like:
<connectionStrings>
<add name="Prod" connectionString="Server=myServer;Database=DB1;user=sa;password=myPassword;Trusted_Connection=false" providerName="SQL" />
</connectionStrings>
Then, in your code, you read the connection string from web.config as follow:
string connString = System.Configuration.ConfigurationManager.
ConnectionStrings["Prod"].ConnectionString;
You're asking a very basic question here and it indicates that you're trying to bully your way into learning c#. My advice to you is to grab a good C# book and go through it cover to cover to learn things the right way.
Instead of putting the connection string into a separate file, store it in your app.config or web.config file. .NET configuration files van contain a section that allows you to store connection strings:
<connectionStrings>
<add name="myConnectionString" connectionString="server=localhost;database=myDb;uid=myUser;password=myPass;" />
</connectionStrings>
You can retrieve this connection string using the following code:
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
I think Poster's question is pretty much valid. Although we can write connection string in Web.config or app.config once and use it in whole project, but there is a drawback of using this technique.
Connection string in web.config or app.config is never safe. These two files are ultimately like text files. There are ways to get the password from them. The security could be broken. So its better to use the connection string in a separate class file and get it in your whole project.
you could create a class which returns a sqlConnection...
public class DBConn
{
private string ConnectionString = "123456789Connection";
public SqlConnection getSqlConn()
{
return SqlConnection();
}
}

Entity Framework Connection String Trouble

I am making a little library(DLL) to manage users and their roles/privileges. The plan is to be able to add this dll to an MVC project and be able to manipulate users/roles/etc. All the data resides in a SQL db.
I am using entity framework for data access.
So when I initialize a new RoleManager(this is the name of the main class in the lib I'm making) I supply it with a connectionString like so:
RoleManager roleManager = new RoleManager(string connectionString);
Then inside the constructor I do this:
db = new RoleManagerEntities(connectionString); //This is the EntityFramework
And I am trying to supply this connection string (among many others)
"metadata=res://*/RoleManager.csdl|res://*/RoleManager.ssdl|res://*/RoleManager.msl;provider=System.Data.SqlClient;provider connection string='Data Source=localhost;Initial Catalog=Login;Integrated Security=True;Connection Timeout=60; multipleactiveresultsets=true'"
And I get the following error:
The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.
This question is a result of having trying to instantiate the EF from my new project without supplying a connection string and without having anything inside my app config for it to default to. Too bad I can't delete it now.
Just copy the connection string information from your DLL config file to your executable config file.
Basically you are trying to instantiate an ObjectContext via this ObjectContext Constructor (String) without passing the string parameter in its expected format and that's the problem.
Here is what you need to do:
1. First create an entry in your in your "test project" app.config because that is the place that the CLR is looking at to find the connection string at runtime.
<configuration>
<connectionStrings>
<add name="RoleManagerEntities" connectionString="metadata=res:///RoleManager.csdl|res:///RoleManager.ssdl|res://*/RoleManager.msl;provider=System.Data.SqlClient;provider connection string='Data Source=localhost;Initial Catalog=Login;Integrated Security=True;Connection Timeout=60; multipleactiveresultsets=true'" />
</connectionStrings>
</configuration>
2. Now change the code to pass the connection string name instead of the actual connection string:
db = new RoleManagerEntities("name=RoleManagerEntities");
The constructor might be looking for a connection string in the connectionStrings setting of your web.config with the name that you pass it as the parameter.
So if you call:
db = new RoleManagerEntities("Foobar");
It is looking for:
I'm not positive that this is the solution but that's what the error message seems to indicate.
I am not an expert on EF, but I don't think that connection string is valid. Try:
metadata=res://*;provider=System.Data.SqlClient;provider connection string='Data Source=localhost;Initial Catalog=Login;Integrated Security=True;Connection Timeout=60; multipleactiveresultsets=true'

Categories