How to use Application Data in an (App.config) connectionString - c#

I've got an SQL Server CE database in a project that I wan't to store somewhere in the %AppData% directory. However I can't find a way to make a reference to the Application Data path in the connection string (in the App.Config)
<?xml version="1.0"?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="EntityConnectionString" connectionString="metadata=res://*/EntityModel.csdl|res://*/EntityModel.ssdl|res://*/EntityModel.msl;provider=System.Data.SqlServerCe.3.5;provider connection string="Data Source=|ApplicationData|\Entities.sdf"" providerName="System.Data.EntityClient"/>
</connectionStrings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>
So far I learned that: %APPDATA% is not supported and using the settings class (like suggested) won't work either (the settings class isn't constructed at the time the exception is already thrown).
Is it possible to use the application data folder (or another special folder) in the connectionString property (in the App.Config)?
Note: it seems like I'm searching for an solution to modify the connection string (in code) as early as possible rather than an native App.Config solution.

Use your custom build environment variable support:
Let you have:
<connectionStrings>
<add name="My" connectionString="..;Data Source=|%AppData%|\Entities.sdf;.." />
</connectionStrings>
The you can use:
using System.Configuration; // requires reference to System.Configuration.dll
ConfigurationManager.ConnectionStrings["EntityConnectionString"].ConnectionString.Replace("%AppData%", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
Next way you can support several environment variables:
var vars = new Dictionary<string, string>
{
{ "%AppData%", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
{ "%Temp%", Environment.GetFolderPath(SpecialFolder.Temp) },
// etc..
{ "%YourNonStandardVar", "YourNonStandartPath" }
};
var result = ConfigurationManager.ConnectionStrings["YourString"].ConnectionString
foreach (var v in vars)
result = result.Replace(v.Key, v.Value);

Related

Read separate web.config file outside the application folder

I need to read web.config file, outside the application's folder (located in any other directory).
I tried this code:
string filePath = #"C:\Users\Idrees\Downloads\New folder\Web.config";
Configuration c1 = ConfigurationManager.OpenExeConfiguration(filePath);
var value1 = c1.AppSettings.Settings["Key1"].Value;
But it is giving me the error:
Object reference not set to an instance of an object.
Because here, c1.AppSettings is an object, but c1.AppSettings.Settings contains not items (hence 0 Count). It is not really loading the AppSettings keys. When trying to read any Key from Settings collection, it gives this error.
Is there any way how to load AppSettings keys from a web.config file outside the application folder.
If I put same file within application folder, then it reads the keys successfully.
This is my sample config file's content:
<?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>
<!--here goes my connection strings-->
</connectionStrings>
<appSettings>
<add key="Key1" value="Value1" />
<add key="Key2" value="Value2" />
<add key="Key3" value="Value3" />
</appSettings>
</configuration>
I have a web application already running on my server. And I need to develop a small utility which has to do some job in database, and I don't want to write db credentials or connection string(and some other additional app-settings) in each application, I want it to read same thing from web.config.
You can using ConfigurationManager to read arbitrary configuration files by opening a mapped exe configuration as follows:
var filePath = #"C:\Users\Idrees\Downloads\New folder\Web.config";
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = filePath };
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var value = configuration.AppSettings.Settings["Key1"].Value;
As I understand from your comment you want some kind of shared configuration accross multiple app on the same computer. You may consider using external file like this :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings configSource="config\connString01.config"/>
<appSettings file="config\config01.config">
<add key="Var3" value="Var3 value from main config file"/>
</appSettings>
in above .config example connectionStrings is sourced from an other file. Below an example what can be such an external config file:
<connectionStrings>
<add name="SQLConnectionString01" connectionString="Data Source=sourcename01;Initial Catalog=cat01;Persist Security Info=True;Integrated Security=true;"/>
</connectionStrings>
Read documentation: ConfigurationManager.OpenExeConfiguration on MSDN
public static Configuration OpenExeConfiguration(
string exePath
)
This is EXE path

Can't get app.config value "connectionStrings"?

I am writing a program in visual studio,now i can't get the value of app.config.My app.config look like this:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="connStr" connectionString="Data Source=Dolphin-PC;Initial Catalog=jsptpd_SYS;Persist Security Info=True;User ID=sa;Password=ccir"/>
</connectionStrings>
</configuration>
And the code i am try to get the value:
try
{
con2 = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
logger.Info("try to get connectionstr success:" + connStr);
}
catch(Exception ex)
{
logger.Info("try to get connectionstr failed:" + ex.ToString());
}
The log's output:
2013-12-14 16:22:28,710 [1] INFO ApplicationInfoLog [(null)] <(null)>
- try to get connectionstr failed:System.NullReferenceException:
object reference not set to instance.
on Jsptpd.JobScheduler.jsptpdJobScheduler..ctor()
location D:\jsptpd\Code\jsptpdJobScheduler\jsptpdJobScheduler\jsptpdJobShedule.cs:line 46
Where is wrong? Why can't read the ConnectionStrings?
Your section is declared as NameValueSectionHandler. As this article points out, this handler returns a NameValueCollection, not the IDictionary that you cast it to afterwards. That's why as IDictionary results in a null value.
Either declare your section as DictionarySectionHandler or change IDictionary to NameValueCollection.
If that config you posted is really what you have, then that config is just plain wrong.... you have two nested <configuration> sections - that won't ever work!
If your config really looks like what you posted, you need to change it to look like this:
<?xml version="1.0"?>
<configuration> <!-- one and ONLY one <configuration> node! -->
<configSections> <!-- directly under <configuration> -->
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<configSections>
<connectionStrings> <!-- directly under <configuration> -->
<add name="connStr" connectionString="Data Source=Dolphin-PC;Initial Catalog=jsptpd_SYS;Persist Security Info=True;User ID=sa;Password=ccir"/>
</connectionStrings>
<quartz> <!-- directly under <configuration> -->
...........
</quartz>
<appSettings> <!-- directly under <configuration> -->
<add key="connStr" value="Data Source=Dolphin-PC;Initial Catalog=jsptpd_SYS;Persist Security Info=True;User ID=sa;Password=ccir"/>
</appSettings>
</configuration>
There should be only one <configuration> section, and all other tags, like <configSections>, <quartz>, <connectionStrings> and <appSettings> should be directly inside the one and only <configuration> element
Check your app.config file attribute set,make sure that Generate Operation is not embeded resource.
Because you read the app.config through ConfiguationManager class,the Configuration read file like this:
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx
•Read and write configuration files as a whole. Your application can read and write configuration settings at any level, for itself or for other applications or computers, locally or remotely. Use one of the methods provided by the ConfigurationManager class to open a configuration file such as SampleApp.exe.config. These methods return a Configuration object that in turn exposes methods and properties you can use to work with the associated configuration files. The methods perform read or write operations and create the configuration data every time that a file is written.
If you set embeded resource,the bin directionary could not generate the SampleApp.exe.config file,so the ConfigurationManager could read your config file.
So if you want to correct the problem,do this
choose the app.config file in resource manager of visual studio:
set the copy to outout dirctionary to:
No copy
set the generte operation to:
None
The problem will fixed.

Reading a connection string from a class library

I am currently struggling to read a connection string from the App.config inside my WinForms application from my Class Library (and Unit Testing).
I added a 'test' entry to the App.config;
<connectionStrings>
<add name="MyConnString" connectionString="Test;" />
</connectionStrings>
My TestMethod looks like this;
[TestMethod]
public void TestConnection1()
{
string connString = "";
if (ConfigurationManager.ConnectionStrings["MyConnString"] != null)
{
connString = ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString;
}
string expected = "Test;";
string actual = connString;
Assert.AreEqual(expected, actual);
}
This, obviously, fails. Actual's value is empty.
What am I doing wrong?
you need to add connection string key into Test project's config as well.
Regarding your comment to DJ Kraze: "#DJ KRAZE, If I put 0 as index, it returns me a connectionstring for SQLExpress "aspnetdb.mdf". If I put 1 as index, I get an exception (IndexOutOfRangeException), so obviously my string is not found."
The problem is you forgot the configuration element. For example:
Referenced from MSDN: Storing and Retrieving Connection Strings
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings>
<clear />
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
</configuration>
The machine.config file also contains a <connectionStrings> section, which contains connection strings used by Visual Studio. When retrieving connection strings by provider name from the app.config file in a Windows application, the connection strings in machine.config get loaded first, and then the entries from app.config. Adding clear immediately after the connectionStrings element removes all inherited references from the data structure in memory, so that only the connection strings defined in the local app.config file are considered.

How do I write an external connection string config file and make my c# application recognize and read it?

My current c# windows form application is using the following code to connect to a database to retrieve information and the it is stored at Setting.cs
public static String connectionString ="Data Source=####; Initial Catalog=###; User ID=####; Password='####'";
I have written out an external Connection.config file and the content would be :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Connection" providerName="System.Data.providername"
connectionString="Data Source=####; Initial Catalog=###; User ID=###; Password='####!';" />
</connectionStrings>
</configuration>
is the above code written correctly? as I sort of just copied and paste online and editted the connection string part as i do not know what does the "add name" and providerName part does.
what i would like to ask is where should i write the code in my forms to read the connection string from my external config file so i can remove the one in my setting.cs file.
thank you.
don mind the ### as it is just replaced by me to represent the information.
You can use config source to split your config files. Example App/web.config:
<connectionStrings configSource="myExternalConfigSource.xml" />
External Config:
<connectionStrings>
<add name="Connection" providerName="System.Data.providername"
connectionString="Data Source=####; Initial Catalog=###; User ID=###; />
</connectionStrings>
More info: http://www.nikhilk.net/Entry.aspx?id=158
If you use this method, you can reference your config as normal and still have your configuration split out into seperate files.
Add the following in your web.config file right at the bottom above the closing config tag.
<connectionStrings>
<add connectionString="Data Source=Servernamegoeshere;Initial Catalog=databasenamehere;Persist Security Info=True;User ID=***;Password=***" name="nameyouwanttogivethisconnection" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
To reference the connection on the page load of the main form use this:
public void Page_Load(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["nameyouwanttogivethisconnection"].ConnectionString;
SqlConnection SqlConnection = new SqlConnection(connectionString);
SqlCommand SqlCommand = new SqlCommand("update table etc etc....",SqlConnection);
SqlConnection.Open();
SqlCommand.ExecuteNonQuery(); //This line is for updates and inserts, use SqlCommand.ExecuteReader(CommandBehavior.CloseConnection); for select statments
SqlConnection.Close();
}
Make sure you add these references to the top of the page you are using this code on:
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
You may then use that connection to create a Sqlcommand to run against your database.
we use:
<configuration>
<appSettings>
<add key="connection.string" value="Initial Catalog=XXX;server=localhost;User=YYY;Password=ZZZ;" />
</appSettings>
</configuration>
and then just:
ConfigurationManager.AppSettings["connection.string"];
You could also use ApplicationSettings, and forget about writing information in config files manually (It will be done automatically)
Right click on your project in solution explorer and select Properties.
Go to Settings tab.
Click on the link to create the settings file. (It will be called Settings.settings)
For Name, type the name you want to use for the connection string. (i.e. ConnectionString)
For Type, select Connection String
For Scope, select Application
For Value paste your connection string.
When you want to use it, just type
Application.Settings.Default.ConnectionString
i.e
SqlConnection connection = new SqlConnection(Application.Settings.Default.ConnectionString);

Multiple SQL Server connection strings in app.config file

I'm interested in displaying in a Windows Forms app a list of N radio buttons for the user to choose a target database server. I would like to add the SQL Server connection strings in the app.config file, so they are read by the app at runtime and rendered in the windows form as radio buttons.
At first I thought of using a delimiter to separate the connections
<appSettings>
<add key="ConnectionString" value="connection1|user id=user;password=123;server=10.0.0.1;database=myDatabase;connection timeout=30|connection2|user id=user;password=123;server=10.0.0.2;database=myDatabase;connection timeout=30"/>
</appSettings>
And then split the key value pairs.
Is it possible to do this in a different way?
To find all defined connection strings from your app.config, use the ConfigurationManager (from System.Configuration).
It has an enumeration: ConfigurationManager.ConnectionStrings which contains all entries in your <connectionStrings>.
You can loop over it with this code:
foreach(ConnectionStringSettings css in ConfigurationManager.ConnectionStrings)
{
string name = css.Name;
string connString = css.ConnectionString;
string provider = css.ProviderName;
}
The Name is just the symbolic name you give your connection string - it can be anything, really.
The ConnectionString is the connection string itself.
The ProviderName is the name of the provider for the connection, e.g. System.Data.SqlClient for SQL Server (and others for other database system). If you omit the providerName= attribute from your connection string in config, it defaults to SQL Server (System.Data.SqlClient).
Marc
Use the connectionStrings section to define your connection strings.
<connectionStrings>
<add name="connection1" connectionString="user id=user;password=123;server=10.0.0.1;database=myDatabase;connection timeout=30"/>
<add name="connection2" connectionString="user id=user;password=123;server=10.0.0.2;database=myDatabase;connection timeout=30"/>
</connectionStrings>
Yes, it is possible to do this in another way. Check the connectionStrings section that you can make in the app.config file.
<configuration>
<connectionStrings>
<add name="" connectionString=""/>
<add name="" connectionString=""/>
</connectionStrings>
</configuration>
We can declare multiple connection string under Web.Config or App.Config
<connectionStrings>
<add name="SourceDB" connectionString="..." />
<add name="DestinationDB" connectionString="..." />
</connectionStrings>
In DAL or .cs file you can access connection strings like this string SounceConnection = ConfigurationManager.ConnectionStrings["SourceDB"].ConnectionString;
string DestinationConnection = ConfigurationManager.ConnectionStrings["DestinationDB"].ConnectionString;
You can use the AppSettings class, get a list of all keys that start with ConnectionString and display them.
Your config file will look like this:
<appSettings>
<add key="ConnectionString_Name1" value="..."/>
<add key="ConnectionString_Name2" value="..."/>
<add key="ConnectionString_Name3" value="..."/>
</appSettings>
You can get the name, by splitting the key name (using "_" in this example).
BTW: You should also use the ConnectionStrings section, you are only interrested in connection strings.
This is how to use LINQ to get list of connection strings:
List<string> connectionStrings = ConfigurationManager.ConnectionStrings
.Cast<ConnectionStringSettings>()
.Select(v => v.ConnectionString)
.ToList();
Or you can build a dictionary of it:
Dictionary<string/*name*/, string/*connectionString*/> keyValue = ConfigurationManager.ConnectionStrings
.Cast<ConnectionStringSettings>()
.ToDictionary(v => v.Name, v => v.ConnectionString);

Categories

Resources