web.config, app.config priority / dependancies and usage on compilation - c#

Just a quick question. I have a solution splitted in multiple projects. In one project, I have the database interactions and my EDMX. In this project, I have my app.config file with some connections strings.
This project, is imported as dependancy in a Web project. In this one, I have my Web.config where are defined (or "overriden") connections strings.
I'd like to know what are the mechanisms used to configure the database connection. From what I understood, the Web.config has all priority over App.config. But what I'm wondering is, is the App.config in dependancies projects used at compilation time ?
For instance :
Project A => app.config :
<connectionStrings>
<add name="A" connectionString="myConnectionStringA"/>
<add name="B" connectionString="myConnectionStringB"/>
</connectionStrings>
And the same in Web.config but with :
<connectionStrings>
<add name="A" connectionString="myConnectionStringC"/>
<add name="B" connectionString="myConnectionStringD"/>
</connectionStrings>
Which one will be used to define the connection to the EDMX ? In one hand, at compile time, logically it would be A & B used to define it, and C & D would be used at runtime.
But i'm not sure about it and for me, once the dll is "configured", I don't see how can C and D be used instead of A & B.
Could someone explain it to me please ?
Thanks !

The config file that is used at runtime is the one related to where you are launching your application. If you launch the projectA it will be the App.config file.
Actually it will be the file generated by the compilation on the proper directory "Debug" or "Release"
When you run your web project it will be the Web.config file there.
The dll isn't "configured" with the values from the config file, they are read when the application starts running and this will depend on the application that is running.
That is why if you change the values they will change when you relaunch the application without any need to recompile the project.

When designing your entities in Visual Studio, the connection string that is stored in the app.config file of the project is used.
Even though you add a reference to the project from the web project, the app.config of the referenced project is not used at all in the context of the web project. Of course, it can be used as a blueprint when adding the connection strings to the web.config.
The config file that is relevant to the web project is the web.config. So when running or publishing the web project, the settings that are used are the ones in the web.config.
They do not override the settings of the app.config in the sense of a fallback like "if the connection string is not configured in the web.config file, then I use the ones stored in app.config".
It is required that you add the connection strings that you want to use when running the web project to the web.config file, otherwise you'd encounter an error if you used the Entity classes.
For details on configuring ASP.NET web applications, see this link.

But i'm not sure about it and for me, once the dll is "configured", I
don't see how can C and D be used instead of A & B.
The config values are fetched when the progam is running, not when it is compiled.

Related

Setting connection string after publishing on IIS Server

I have two projects, an asp.net MVC project called Home and a c# class library project called Home.Dao.
Home is a simple MVC Project with no connectionstring property in its web.config
Home.Dao is a c# class library project and it is responsible off all the interactions between the code and the database. It has an app.config and contains a connectionstring property
When publishing the Home project in IIS server, I can only find these files (web.config, Hom.Dao.dll, ... etc ) there is no app.config published. My problem is I cannot set the connectionstring after publishing. So I have two questions in mind :
How is it possible to set connectionstring from web.config so this
connectionstring can be used on Home.Dao
Is possible to publish also the app.config ?
To answer your questions:
It is not only possible, it is necessary to set the connection string from web.config
You could copy the app.config to the output directory, but that wouldn't be of much use to you.
To explain why:
Configuration files are only created for the top-level application. For web applications this is the web.config file which is copied to the output directory. For executables the app.config is renamed to -executable name-.exe.config. Configurations are only read from the top-level application config. All settings you need have to be there. So if you transfer your connection string to your web.config, you're good.

Forcing Entity Framework and ASP.MVC to use the connection string from app.config of another assembly

Set & settings:
I use Entity Framework 5 and have a dll project with edmx file. In this project I have App.config with connection string for the EF model. I have also second project, ASP.MVC 4 web application which is a startup project. It references the database project. Important thing is - db is Oracle and EF uses Oracle custom providers.
Problem:
If I place my connection string in the ASP.MVC startup project is works fine. It's common advice to do this. But I don't want to. I don't see reason why I should. How can I force MVC/EF to find the connection string in App.config of the external library (which as a matter of fact is a data access layer)?
App.Config is used by WinForms, WPF and executable applications.
Web.Config is used in IIS (and is able to set IIS environment specific configurations)
It seems no App.Config will ever be merged to the Web.Config (source):
In using an App.config, file the configuration system merges the
App.config file with content of the Machine.config file when the
application starts and the configuration is applied. This mechanism
allows machine-wide settings to be defined in the Machine.config file.
The App.config file can be used to override the settings of the
Machine.config file; you can also lock in the settings in
Machine.config file so that they get used. In the Web.config case, the
configuration system merges the Web.config files in all directories
leading up to the application directory into the configuration that
gets applied. For more information about configuration and the setting
priorities, see topics in the System.Configuration namespace.
Perhaps you'll find a solution more appropriate to your needs by using Application Configuration Files.
Finally, after facing multiple issues, I've decided to move connection string of DAL into the Web.config of the web application. I was convinced by some arguments you can read here in the post of Chris Ammerman.

How to open specific .config file in multi project solution?

Solution that I am working on is made of number of projects, one of them is start-up project(Windows Forms, .exe project) and has app.config file tied to it. At least one of the project(all other projects are .DLLs), that deals with database, will also needs to read app.config settings (to read db connection string). I want to centralize all of the application settings in one app.config file.
My questions are:
From what I understood, application configuration files are created per projects, not per solution ?
To access the app.config from DLLs should I use ConfigurationManager.OpenExeConfiguration(string exePath), where string exePath is the location of .exe for start-up project ?
Config files are connected to application domains, not DLLs. You can access your appication's (let's say web application or console application) configuration directly with ConfigurationManager class (OpenExeConfiguration not required).
If you need different connection strings in different part's of the application, you can add multiple connectionstrings in your configuration
<connectionStrings>
<add name="Connection1" connectionString="Data Source=..." />
<add name="Connection2" connectionString="Data Source=..." />
</connectionStrings>
and access them by name:
var connectionstring1 = ConfigurationManager.ConnectionStrings["Connection1"].ConnectionString;
var connectionstring2 = ConfigurationManager.ConnectionStrings["Connection2"].ConnectionString;
Visual Studio creates an app.config for each project, but only to provide a place to store configuration items for that assembly (since it could be used by multiple executing assemblies). Those configuration items should be incorporated into the app.config of the executing assembly.
You can add code to pull from multiple config files, but it's cleaner just to put them all in one app.config for the executable.
You need to copy all the project specific configuration (like connections strings etc.) into the the main app.config.

How to read values from App.config in .Net 4.0 using configurationManager?

I am creating a windows service in .Net 4.0 and testing some functions of said service with a windows forms client by referencing the service project.
The service project has an App.config file and that file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<clear />
<add name="myLocalMySQLDBUsername" connectionString="username"/>
</connectionStrings>
</configuration>
When a function belonging to the service calls:
ConfigurationManager.ConnectionStrings("myLocalMySQLDBUsername").ConnectionString
a null reference error is thrown because my connection string is not loaded. The only connectionStrings that are loaded are from the machine.config file located in c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Config\machine.config
If I create an application scope setting for the service, I can get that setting by using the My.Settings.setting -> so it's not like the App.config file is not being read.
My question is: why are my connectionStrings not being loaded from the App.config file?
Thank you for your help.
UPDATE:
Also, at this point, even a work around would be appreciated; the only reason for using app.config is to be able to encrypt the contents using the DpapiProtectedConfigurationProvider (the contents will have some username/password values for service and database connections).
I tried creating an AppSettings section manually in the app.config but those settings were also not read by the configurationManager (count = 0).
UPDATE 2:
Per a suggestion, I tried to manually open the app.config file like so:
Dim exePath As String = System.IO.Path.Combine(Environment.CurrentDirectory, "ServiceName.exe")
Dim myConfig As Configuration = ConfigurationManager.OpenExeConfiguration(exePath)
So here is the weird part, when I look inside, path is correct (points to my app.config) but the connectionStrings are still being loaded from the machine.config file (my connectionStrings are not loaded)!! ARGH
UPDATE 3:
Okay, so, I figured it out. When referencing a project(parent) from another project(child), the child's app.config is used even if the parent's classes are being used. Thus, I can get the connectionStrings to show up if I copy them over to the child's app.config. When trying to open it manually, my currentDirectory was of the child, not the parent (strange how it did not throw an exception - it wouldn't have been able to find the config file ... it just silently used the machine.config ... oh well).
Thanks all for the help!
The first thing you'll want to do is make sure that the service account has access to the file (if not running as SYSTEM). It sounds like it should be ok though since you mention My.Settings.Setting works.
The other thing to look out for is to make sure that the app.config has the name of the service executable in it - so if the service exe is MyService.exe the app.config must be named MyService.exe.config.
The last thing to make note of: libraries will read from the executable's app.config that loads the library, not the app.config that is with the library. So if you have a project for the service executable MyService and a project for the library MyServiceLibrary the code in the library will read the app.config from MyService not MyServiceLibrary.
I saw some people say this problem might be fixed by manually re-adding a reference to System.Configuration.dll
SIDE NOTE: If that really is you whole app.config file and not just a snippet then that is your problem... you're app.config file should be MUCH more complicated or .NET will not be able to load it.
WORK AROUND: Use the configuration manager to open this config file (there is an API for that.) You can't get it to load auto-magically just tell the config manager to open it.
I still think the problem is your config file is invalid -- could you please post the FULL file?
Make sure the config file is deployed to the same folder as the executable file, and that it's called your.assembly.exe.config.
I had a similar problem, but in my case it was because I had changed the project's namespace. This is also used as the application settings section element name in the config file, so the code was not finding the new section name. Fiddling with one of the custom setting's values in the project properties and rebuilding caused the new section to written into the app.config alongside the old ones which was what indicated the issue to me.

ConfigurationManager.AppSettings getting null?

I did not realize that: 'have a web.config in a separate class library and' was reading the web.config app setting from different web application.
I am using VS2010 target framework 3.5
I don't know what is wrong here but I am getting null when I try to get ConfigurationManager.AppSettings["StoreId"];
private string _storeid = GetStoreId;
public static string GetStoreId
{
get
{
return ConfigurationManager.AppSettings["StoreId"];
}
}
web.config:
<appSettings>
<add key="StoreId" value="123" />
</appSettings>
If you are UNIT TESTING you need A COPY of the APP.CONFIG inside the UNIT TEST PROJECT
Update
You can have an AfterTargets in your CsProj file that copies the config:
<Target Name="CopyAppConfig" AfterTargets="Build" DependsOnTargets="Build">
<CreateItem Include="$(OutputPath)$(AssemblyName).dll.config">
<Output TaskParameter="Include" ItemName="FilesToCopy"/>
</CreateItem>
<Copy SourceFiles="#(FilesToCopy)" DestinationFiles="$(OutputPath)testhost.dll.config" />
</Target>
Problem
The usual cause for this is due to context.
Cause
When you have a solution with two projects, if the App/Web.Config is in the main project it wont work if the context of the running application is the second project such as a library, unit test, etc.
Conundrum
To read values from the config in other projects (with System.Configuration) you'll need to move/copy the config file to the project with the running context. Unfortunately duplicating files defeats the tenants of good programming; OOP, Source Code Management, SOLID, etc.
Cool Solution
A nifty solution is adding config file shortcuts in other projects so you only update one file:
It would be nice to divide the contents of config files across project's. Elegantly, like Sharing Assembly Files as per answer #2: https://stackoverflow.com/a/15319582/495455 but alas it's by context
Disclaimer ;) This post is not to answer OP as it is too late but definitely it would help the readers who end up to this page.
Problem I faced : ConfigurationManager.AppSettings["uName"] returning null in my C# web api project.
Basic Things I checked for :
1) In code ConfigurationManager.AppSettings["uName"] , I was using exact key 'uName' as I had in web.config file,
i.e
<appSettings>
<add key="uName" value="myValue" />
</appSettings>
Checked that I haven't mis typed as userName instead of uName etc.
2) Since it is a Web API project it would have a file as web.config instead of app.config , and that too in root folder of your project. [refer the image].
Solution :
The solution that worked for me ,
Changed ConfigurationManager.AppSettings["uName"] to WebConfigurationManager.AppSettings["uName"]
and
made sure that I had
<appSettings>
<add key="uName" value="myValue" />
</appSettings>
in the right file ie.
Right file is not web.config in View folder
neither the debug or release web.config
and:
<appSettings>
<add key="StoreId" value="123" />
</appSettings>
is located in the web.config file of your ASP.NET application and not in some app.config file you've added to your class library project in Visual Studio, right? You can't be possibly getting null if this is the case. If you've added this to an app.config of you class library project in Visual Studio then getting null is perfectly normal behavior.
I just got answer DLL are called from another project not in the project where there are create.so entries in App.config should b move to calling project config file.
For example i have 2 project in my solution one class library and other console application.i have added class library reference in Console application.So if i add app.config file in class library project it through null exception.it works when i added app.config in console application.Hope it works
App settings are loaded into ConfigurationManager.AppSettings, but User settings (in Properties settings in your project properties) are not.
In Visual Studio, right-click on the config file, select Properties, and then change "Copy to Output Directory" to either "Copy always" or "Copy if newer".
Alternatively, manually add the following section as a child of the element in your .csproj file (this one is for "Copy always" for file "App.config"):
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
I tried all of these solutions but none worked for me. I was attempting to use a 'web.config' file. Everything was named correctly and the files were in the proper location, but it refused to work. I then decided to rename my 'web.config' file to 'app.config' and just like that, it worked.
So if you are having this issue with a 'web.config' file be sure to rename it to 'app.config'.
This happened to me when I was testing a Class Library (.dll). They were both in the same project but the App.config for the library had the settings I needed. The App I had written to test needed the settings because it was running the library.
I got this problem as I copied a project from the file explorer and renamed the project. This copied the Debug folder and as I didn't have it set to 'Copy if newer' it didn't overwrite the old App.config file.
Just delete the Debug folder and rebuild. Hope that helps someone.
I agree with above answer and I would like to add few more points
you should make sure you don't put space before and after the :
see code below:
private static string Client_ID = ConfigurationManager.AppSettings["ida:ClientId"];
if you put space between ida: ClientId it will not work and will return null
make sure your key value names are correct
you can try WebConfigurationManager
Happened to me just now, only when calling it from another project.
Apparently, at the other project, the reference has not been defined as a Service Reference but rather as a Connected Service. I deleted the reference and added it again.
string setting = ConfigurationManager.AppSettings["Setting"];
Make sure config file is in the same folder as code referencing it. Create a
helper class if it is not. Duplicating this could cause confusion should
someone forget it exists in two places.
Keep app settings in an app.config and not a web.config for AppSettings.I had this issue with a key in the web.config.

Categories