C# ConfigurationManager retrieves wrong connection string from app.config - c#

I have a simple WinForms app that will eventually be a game. Right now, I'm just working on the data access layer of it and I've run into a snag. I created a separate project called DataAccess and inside of that, I created a local .mdf SQL Server database file. I also created an app.config file to store the connections string.
Here's that config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="TBG_Master"
connectionString="Data Source=(localdb)\MSSQLLocalDb;Integrated Security=true;AttachDbFileName=|DataDirectory|\TBG_Master.mdf"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
To retrieve the connection string from the app.config file I am using code pulled from this question.
Assembly service = Assembly.GetExecutingAssembly();
ConnectionStringsSection css = ConfigurationManager.OpenExeConfiguration(service.Location).ConnectionStrings;
string cs = css.ConnectionStrings["TBG_Master"].ConnectionString;
return cs;
When it gets to the line where it pulls the connection string using the string as the key, it gives me a null reference exception. After examining the css.ConnectionString collection, the only connection string it has in it looks like this:
data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true
This is clearly not what it is in my app.config file, and I know there is no other app.config file in my DataAccess project. Also after debugging, I know for a fact that it is looking in the right assembly.
Why is it giving me this connection string and not the correct one?

As #Amy pointed out, the reason this was not working was because the connection string was not stored in the executing assemblies app.config file. After moving it, it now works as it should. Thank you for the quick help :)

You can also use the machine.config file to hold connection strings that are independent of any application for a given machine. That way they don't have to be in any app.config file, because all applications automatically read the machine.config file on the machine they are executing on.

Related

Can't find App.config file for Windows Console app

I have a Windows console app that has an App.config file. The console app is to be executed from a SQL Agent job. In app.config I store a database connection.
<connectionStrings>
<add name="Northwind" connectionString="Data Source=servername;Initial Catalog=Northwind;User ID=sqlUser;Password=secret" providerName="System.Data.SqlClient"/>
</connectionStrings>
I get the connection string at runtime like so:
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
My code works fine in debug and can read the connection string from App.config.
When I build for release, there is no app.config in the release folder. When I copy the .exe over to the server, I get "Object reference not set..." when trying
to get the connection string. Tried manually copying app.config, but no joy.
Found this, but it doesn't match since my build doesn't create a file named MyApp.exe.config.
Edit: It doesn't create any file ending in *.exe.config.
Loading app.config file in Release
What am I doing wrong?
Edit: Does the App.config become a part of the .EXE in a Windows console app?

Read configuration from App.config instead of AppName.exe.config

I have developed a small windows service which performs few database operations. I have to give an option to the user to change server name on post-deploy. if user changes in app.config it doesn't affect the service, it is still reading connection strings from AppName.exe.config.
Here what I have tried.
<connectionStrings>
<add name="testString" connectionString="Data Source=ServerAddresss;Initial Catalog=DatabaseName;Integrated Security=True;" />
</connectionStrings>
C# code,
ConfigurationManager.ConnectionStrings["ProjectName.Properties.Settings.testString"].ConnectionString);
This returns a server connection string from AppName.exe.config file but I want to access it from App.config file.
can someone help me out in this?
App.config and AppName.exe.config aren't exactly separate - AppName.exe.config is the build output of app.config.
In other words, once the service is deployed, there shouldn't even be an app.config to change, and if there is, changing it won't do anything. AppName.exe.config is where your application gets "app.config" values.
If you need different configuration values for different environments, take a look at config transformations. They allow you to change or replace sections or individual values for different configurations such as debug, release, or other custom configurations.
This is useful because it means that all of the connection strings are part of the project and are in source control. You can do without this and just edit the config file in place on the server, but then there will be nothing in source control indicating where the connection string came from. And then if you redeploy the service the change will be overwritten unless someone remembers to make the same change every time. Having it in source control is much better.
For some reason that I do not understand, you can right-click a web.config and select "Add Config Transforms", but you can't do that with an app.config. Maybe there's a good reason.
You can install this extension which enables the same behavior for app.config. Then you can right-click on app.config and add a transformation for another configuration, like Release.
In that file (app.Release.config) add this:
<connectionStrings xdt:Transform="Replace">
<add name="testString" connectionString="...your Release connection string..." />
</connectionStrings>
When you build and deploy using the Release configuration it will replace the connectionStrings section with this one, leaving everything else just as it is. You can also right-click app.Release.config and select "Preview Config Transforms" to see the transformed file side-by-side with the original.
You should be able to just pull in an arbitrary file with a ConfigurationFileMap
System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
This question is a possible duplicate of: Using ConfigurationManager to load config from an arbitrary location
Also, you'll have to be sure that the service is restarted after updating the config file (either config file).

Why is app.config working abnormally?

My problem is solved but I don't quite understand the solution and why it worked. I made a class library "Business Layer" inside a solution which also contains a Windows forms project (C#). Within the class library I put an app.config file and defined a connection string inside it, which I used in SQL-connection code in the business layer. Then I called the database logic in the Windows forms application, but the project failed at the connection string part (i.e., it returned null). However, when I copied app.config to the application project it started working. Why? Why is it that if I am using all database code in the business layer that pasting the code in the application project worked?
Code:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="ConnectionString" connectionString="Data Source=HOME-PC;Initial Catalog=LMS;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
getting:
string conStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString.ToString();
You are using the following code in your program:
string conStr = ConfigurationManager.ConnectionStrings["ConnectionString"]
.ConnectionString.ToString();
So, what does this do? Why is this important?
ConfigurationManager will look for the app.config or web.config (if you are making a web site) that corresponds to the running program. For example, if you have a program called "MyCoolProgram", you would have two output files called "MyCoolProgram.exe" and "MyCoolProgram.exe.config".
It's because of this naming structure that the ConfigurationManager is able to work.
But you already made an app.config, right? You made one in your referencing dll project. Why do you have to make another app.config with the same values?
So let's add in another project to our example. So far our example solution looks like this:
MyCoolProject (exe)
CommonLogic (dll)
If both projects have their own app.config file, the files listed in MyCoolProjects' bin folder would look like this:
MyCoolProject.exe
MyCoolProject.exe.config
CommonLogic.dll
So first, where is the config file for CommonLogic? It's not there. By default, a class library's config file is not copied over with the dll file, but you can see it still exists in CommonLogic's bin directory.
Second, so let's say that you do copy over CommonLogic's config file. You will have a file called CommonLogic.dll.config in MyCoolProject's bin directory. However, with "MyCoolProject.exe.config" empty, your code still can't find the connection string. It's strange because,
The connection string is set (only) in CommonLogic.dll.config
The code that is trying to get the connection string is from CommonLogic
So what gives?
Remember what I said before: ConfigurationManager will look for the app.config that corresponds to the running program, not the assembly that the code was ran from. No matter where your code is, the Configuration Manager is going to look at "MyCoolProject.exe.config" for any values. It's not going to look at anything else. For all intents and purposes, it doesn't even know about any other libraries or config files.
This means that you need to put your connection string (preferably exclusively) in the program that will be consuming the referencing library.
The class library should not be in charge of setting the connection string, that should be up to the program that uses it.
when I copied app.config in actual application project too then it started working, why ?
Because app.config is for the application, not the library. VS just gives you an app.config for a library to show you what should be put in the application configuration file.
It's perfectly reasonable to assume that a library can be used in multiple applications with different configurations, so tying the configuration to the library would make it harder to separate the configuration between applications.

Where to put EF Connection String?

I am working on a project with plugin architecture in VB.NET. I have two projects: PublicInterfaces which includes my IPlugin interface and some other codes which will be shared on other projects, and DemoApp which has a reference to PublicInterfaces's assembly.
My Data model is and edmx file is located in PublicInterfaces, but in run-time, it gives me an error like this:
No connection string named 'HRMSApplicationEntities' could be found in the application config file.
while my App.config File of PublicInterfaces contains it!
<connectionStrings>
<add name="HRMSApplicationEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=HRMSApplication;user id=sa;password=Hamckerma;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
But the strange thing is when I put this into DemoApp's App.config file, IT WORKS WITH NO ERRORS!
Where should I put the connection string?
When you build DemoApp, you will have DemoApp.exe.config in debug/release folder, which is the application's configuration file.
DemoApp and every referenced dll (including PublicInterfaces.dll) will look in this configuration file. So you only need to add connection string in DemoApp's App.config file and it should work fine.

How can I access the connection string in my Web.Config file through a Windows Application

I have my Entity Connection String set in my Web.Config file. In the same solution, I have a Windows Application, and I want to access the Connection String of my Entity. How can I access the connection string that exist in my Web.Config file? Or I have to create a specific one in my Windows Application ?
If you're unfamiliar with adding a config file to a windows app, you must select an "Application Configuration File" from add new items, it will create a file named App.Config which will at compile time become YourProgramsName.exe.config but internally it works mostly just like a web.config with an appsettings section and connectionstrings sections and all the other normal sections.
The best way to share this data between Web and Win config files would be:
Create a separate file that looks like:
<connectionStrings>
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
and reference it from both config files with:
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings configSource="connections.config"/>
</configuration>
Then just add the connections.config (add existing item by link) to each project.
More reading: http://msdn.microsoft.com/en-us/library/ms254494.aspx
Put the connection string your windows application's App.config.
use this code:
string connectionString = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;

Categories

Resources