DataDirectory is not getting replaced in my code WPF - app.config - c#

I've been trying to set a connectionstring to the users programdata folder and followed the first step in the answer of this post:
%APPDATA% in connection string is not substituted for the actual folder?
Unfortunately I can't get it to work:
In the onstartup method of my WPF application I run the following:
AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
var test = AppDomain.CurrentDomain.GetData("DataDirectory");
var connection = System.Configuration.ConfigurationManager.ConnectionStrings["Conn"].ConnectionString;
Value in App.config
<add name="Conn" connectionString="data source=|DataDirectory|\mydb" providerName="System.Data.SQLite" />
result of test = "c:\programdata" => this is good
result of connectionstring ="|DataDirectory|\mydb" => this is not good
I'm expecting: "c:\programdata\mydb"
I've been looking all around... what am I doing wrong?
thanks in advance,

You are misunderstanding how it works.
Setting the DataDirectory is correct, but the actual connectionstring is not changed on file.
When you open the connection the |DataDirectory| part of the string will be replaced with your path
You just need to try and see by yourself

If you're following the answer you linked to, you seem to be missing the following from Step 2. in the link:
return connection.Replace("%APPDATA%",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));

Related

Why does my connection string not work that I added in my App.config?

I have my connection string set up in the app config but I can not get it to find that connectionstring or even see that the connection name currency is in the collection.
I tried to add a version.
I have tried to adding the provider name to the string.
I have moved it in and out and in again of the path where the database and solution are located.
I have carefully made sure that I was pointed to the right location on my computer.
<connectionStrings>
<!-- CHANGE THIS to match where your solution and sqlite database are -->
<add name="currency" connectionString="Data Source=F:\CurrencyExercise\currency.db" />
</connectionStrings>
And then the code that calls the above.
public BaseDataAccess(string connectionName = "currency")
{
_connectionName = connectionName;
Connection = new SQLiteConnection(ConfigurationManager.ConnectionStrings[_connectionName].ConnectionString);
Connection.Open();
}
I would expect the code to actually pull back a SQLiteConnection object rather than erroring out.

Value cannot be null. Parameter name: path

I'm working with a local dataBase in a Windows Form Application and I'm trying to implement the source for the dataBase as DataDirectory, so in case I'm moving the db from one computer to another, it will work just fine. I wrote the following code, but I get this error, that the value cannot be null, at the line where it gets the Fullpath. Thanks !
var dataDirectory = ConfigurationManager.AppSettings["DataDirectory"];
var absoluteDataDirectory = Path.GetFullPath(dataDirectory);
AppDomain.CurrentDomain.SetData("DataDirectory", absoluteDataDirectory);
var connString = (#"Data Source= |DataDirectory|\Angajati.sdf");
You should have this section in your app.config:
<appSettings>
<add key="DataDirectory" value="DataDirectoryPath"/>
</appSettings>
By the way for accessing DataDirectory you have to use this code:
AppDomain.CurrentDomain.GetData("DataDirectory")
more info.

App.config's element values to be used in Connection String

Is it possible use App.config's value in Connectionstring. Example is mentioned below.
<appsettings><add key="UserName" Value="abc" /></appsettings>
<connectionstring><add name="Conn" connectionString="Server=test; Database=test; Uid=UserName; Pwd=test123;" />
So as you can see that I have defined the Username in appsettings and I want to see that into the connection string
Any help is appreciated.
As I know, it's impossible.
You can use different App.config files for different configuration (Debug, Release) and set your connection string in them.
Look here or here
You can use String.Format().Just change Uid=UserName; to Uid={0};".
String connectionString = String.Format(ConfigurationManager.ConnectionStrings["Conn"].ConnectionString, ConfigurationManager.AppSettings["UserName"].Value);

Set the database location in the connection string thought AppDomain.CurrentDomain.SetData

I've found out how to use the |DataDirectory| in the connection string to set the directory where my wpf app's database file resides, but I wish to go a little further.
As stated in the msdn SqlConnection.ConnectionString Property,
The path may be absolute or relative by using the DataDirectory substitution string. If DataDirectory is used, the database file must exist within a subdirectory of the directory pointed to by the substitution string.
Now, i want to set the full location, not just the DataDirectory, with a custom DatabaseLocation attribute which is controlled by the application and thus I won't need to handle the connection string.
In other words, my connection string will go from this:
connectionString="Data Source='|DataDirectory|\database.sdf'" providerName="System.Data.SqlServerCE.4.0"
into this:
connectionString="Data Source='|DatabaseLocation|" providerName="System.Data.SqlServerCE.4.0"
and in the code, I'll read the user configuration and set the convenient data to the proper location:
AppDomain.CurrentDomain.SetData("DatabaseLocation", someVarWithDatabaseLocation);
This way I'll not need the content of the someVarWithDatabaseLocation from the user interface to the business down to the dataaccess and create a connection string.
Is this possible, or only the |DataDirectory| magic tag is treated by the connection string builder?
Thank you
Well. There isn't.
After decompiling System.Data (sorry) and analysing the available ConnectionString constructors I saw that there is only ExpandDataDirectory and it has hardcoded to the
const string DataDirectory = "|datadirectory|";
So... only datadirectoy is handled...

%APPDATA% in connection string is not substituted for the actual folder?

When using WPF and entity-framework I have an APP.CONFIG that looks like the following:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="DatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlServerCe.4.0;provider connection string="Data Source=%APPDATA%\Folder\Database.sdf"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
When using this code it always throws the following error:
System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlServerCe.SqlCeException: The path is not valid. Check the directory for the database. [ Path = %APPDATA%\Folder\Database.sdf ]
When I run the path "%APPDATA%\Folder\Database.sdf" from the command prompt it works fine, and if I remove "%APPDATA% and hardcode the path it works fine - so it looks simply like the %APPDATA% is just not being substituted for the actual folder...
Thanks,
As you already reallized, %APPDATA% or any other environtment variables are not replaced with their respective value in connection strings. Environment varialbes are something related to the operating system shell. They work in command prompt because the command prompt explicitly parses the values entered and substitutes environment variables. That's not something that .NET Framwork usually performs.
To achive this, you have to manually provide the value for %APPDATA% (using Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) or Environment.GetEnvironmentVariable("APPDATA")). There are two options:
Change your connection string and use |DataDirectory|:
<connectionStrings>
<add name="DatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlServerCe.4.0;provider connection string="Data Source=|DataDirectory|\Database.sdf"" providerName="System.Data.EntityClient" />
</connectionStrings>
(Notice the use of |DataDirectory| in the path to the database file.)
Then provide the value for |DataDirectory| in your application's Main method:
AppDomain.CurrentDomain.SetData("DataDirectory",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
Refer to this MSDN page for more information.
Manually provide the connection string for your ObjectContext class. This way you can parse and change the connection string:
public static string GetConnectionString()
{
var conStr = System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseEntities"].ConnectionString;
return conStr.Replace("%APPDATA%",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
}
And later:
var db = new DatabaseEntities(GetConnectionString());
Or subclass you ObjectContext class and always use the new connection string:
public class MyDatabaseEntities : DatabaseEntities
{
public MyDatabaseEntities()
: base(GetConnectionString())
{
}
public static string GetConnectionString()
{
var conStr = System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseEntities"].ConnectionString;
return conStr.Replace("%APPDATA%",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
}
}
and use the new class anywhere.
I have another option. We don't need to replace anything. I am using below connection string without any replace and it's working fine.
<connectionStrings>
<add name="ProjectManagementDBEntities" connectionString="metadata=res://*/Models.ProjectManagementModels.csdl|res://*/Models.ProjectManagementModels.ssdl|res://*/Models.ProjectManagementModels.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\ProjectManagementDB.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
</connectionStrings>
Main change is data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\ProjectManagementDB.mdf;integrated security=True;
I hope this will save someone.
You have to replace the %APPDATA% in the code with the relative path -
var connectionString = ConfigurationManager.ConnectionStrings["DatabaseEntities"]
.ConnectionString;
connectionString.Replace("%APPDATA%",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

Categories

Resources