C# console app can't read auxiliary App.config - c#

I have a C# console app. It reads values from App.config.
Within App.config I make use of the file property of the appSettingssection.
In this way I can have a secondary configuration file that should supplement/overwrite properties defined in the primary configuration file.
However I find that the properties in the secondary file are not available at run time.
App.config (extract)
<appSettings file="App-not-in-source-control.config">
<add key="THIS_IS_A_TEST_KEY" value="Test Value" />
....
</appSettings>
App-not-in-source-control.config
<appSettings>
<add key="SOMEVALUE" value="foobar"/>
</appSettings>
Program.cs (Extract)
//THIS WORKS
var only4dbg = ConfigurationManager.AppSettings["THIS_IS_A_TEST_KEY"].ToString();
//THIS DOESNT WORK
var someValue = ConfigurationManager.AppSettings["SOMEVALUE"].ToString();
The attempt to read SOMEVALUE results in the following exception
Unhandled Exception: System.NullReferenceException:
Object reference not set to an instance of an object.
Is there something I've overlooked here ?

OK well having written that all out I realised what the problem was.
The secondary config file is only available to the run time if you've set the 'Copy to Output Directory' property of the file to something other than 'Never' ('Never' is the default setting).
It's strange to me that 'Never' is the default setting ; it's not the case for the 'App.config' and the secondary config (at least in my case) was created using the 'Add | New Item | Application Configuration File' dialog sequence within 'Solution Explorer' - there doesn't seem to be much point asking Visual Studio to create a config file which isn't going to be available to the project build output.
Regardless that's the way it is - hope this helps someone else.

Related

Where has my Settings Editor gone in my Project Properties Menu?

I'm trying place a DB connection string in an app config file for my C# console project in VS Community 2019 so I can access the string from a central location. I had to create an app.config file by adding a new one to my project. When I try to access it using the ConfigurationManager, I get a NullReferenceException 'Object not set to an instance of an object'.
These are my App.config file contents:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name ="DBConnection"
providerName="System.Data.SqlClient"
connectionString = "Data Source=(localdb)\ProjectsV13; Initial Catalog=DATAMINE; Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" />
</connectionStrings>
<customSettings>
</customSettings>
</configuration>
And for the sake of simplicity, I'm attempting to access via:
using System;
using System.Configuration;
public class Program
{
static void Main(string[] args)
{
var sd = ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
}
}
While troubleshooting I went into my project's Properties in order to access the Settings Editor, but the menu option isn't present (see pic). I even tried creating a new console application, checked its Properties and the Settings Editor doesn't exist there either. I appreciate any help!
Missing Settings Editor from Visual Studio Community 2019
I had the same issue with the Properties/Settings.Settings.
right click on Settings.Settings
choose "Open with"
Select "Settings Designer"
click "set as default"
https://developercommunity.visualstudio.com/content/problem/962124/propertiessettings-editor-view-missing.html
I test the code with your App.config, and it can get the connection string. Also, I recommend using appSettings instead of customSettings.
As to Settings, it can be found in Visual Studio Enterprise 2019.
It took all day looking through the forums for this one. I'm using .NET Core 3.0 in Visual Studio Community 2019. Basically, my ConfigurationManager was trying to access a config file from ~\bin\debug\netcoreapp3.0\DESCLogicFramework.dll.config. Where this file originated from I have no idea, but I assume it was just created automatically on building my app. Bottom line, I had to overwrite it.
On a side note: I found this out using:
var configfile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
and then exploring the configfile object in the debugger, and finding a property called "Filepath".
The steps I took to correct it were:
Rename my app.config file to be 'assemblyname'.exe.config, for example mine ended up being "DESCLogicFramework.exe.config"
Place this config file in my root project directory.
Change the config file Build Action Property to "Application definition" and its "Copy to Output Directory" Property to "Copy if newer". Both these can be accessed by right clicking on your config file and selecting "Properties". It will bring up the Properties window.
Opening up the project's .csproj file, and adding the following lines of xml right before the closing ProjectTag, you tell the build to copy your .config file to the build location and give it the .dll.config extension.
<!-- START: This is a buildtime work around for https://github.com/dotnet/corefx/issues/22101 -->
<Target Name="CopyCustomContent" AfterTargets="AfterBuild">
<Copy SourceFiles="DescLogicFramework.exe.config" DestinationFiles="$(OutDir)\DescLogicFramework.dll.config" />
</Target>
<!-- END: This is a buildtime work around for https://github.com/dotnet/corefx/issues/22101 -->
Afterwards, I made sure the project was "using System.Configuration" and accessed the file contents with
var conn = ConfigurationManager.ConnectionStrings["DBconnection"];
Edit:
I am still not seeing the Settings Editor in my Project Properties, but I was able to solve the issue I was having without it.

Cannot read data from app.config in Windows 10 & asp.net

I am working on a asp.net application that stores important data in app.config. In all Windows versions before Windows 10, the tests correctly load the data I want, but once I upgraded a system to Windows 10, the application no longer is able to pass the same test and fails to grab data. Whenever it read from the app.config file, as seen in the code below, Null is always returned.\
var data = System.Configuration.ConfigurationManager.AppSettings["PathName"];
When run in Windows 8, the value returned is a valid string that I use. When run in Windows 10, null is returned despite the file being present just as before. Once the value is used later on in regards to path3, an Exception is tripped and the error shown below occurs. Path3 comes from a function that the Null value is passed into.
threw exception: System.ArgumentNullException: Value cannot be null. Parameter name: path3
I have tried changing user permissions to files, folder and so on, but nothing seems to change this. I have also changed the User Account Control settings with no luck. I am using Visual Studios 2013 Professional and always run it in under admin mode.
Everything I have looked at online has not helped much and pretty much reiterates most of the steps I have already tried. Any insight is greatly appreciated.
Contents of app.config (Key = "PathName")
<?xml version="1.0"?>
<configuration>
<configSections>
</configSections>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
<appSettings>
<add key="PathName" value="DATA_VALUE_NEEDED" />
</appSettings>
<applicationSettings>
</applicationSettings>
</configuration>
So, after trying a lot of solutions, I finally figured out what was creating the problem. I'm not exactly sure why this occurred, but this is what happened all the same.
On windows 8, the app.config file from test projects loads directly from the main project it is meant for. Meaning, if you create a separate project for your tests, it links to the original that it was created for when loading app.config files.
In Windows 10, this does not seem to be the case for some reason. For some reason, the app.config file being read in was not the one for the project the tests were created for. It was some sort of auto generated default despite no settings or configurations being changed between porting the code between the two OS versions.
I was able to solve the problem by copying the file directly from the main project into the test project for it. Then, with a link between the two, they will stay updated when either one is changed.
I still don't understand why this happened and cannot locate the generated app.config file. After debugging, I simply noticed that the loaded key value pairs available did not exist in any single XML files in the entire project repository. Hopefully this helps others down the road with the same problem since I have seen several other reports online of people running into what seems to be this problem. Thanks everybody for your help!

How does AppSettings in VB.NET windows Forms work?

Hello I have build a small app to demo a concept in C# in which I added the application config file etc added System.Configuration dll to the reference and accessed the settings:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="username" value="myknownusername"/>
</appSettings>
</configuration>
No news It worked flawlessly with the code:
private String username = ConfigurationManager.AppSettings["username"];
Now I have been asked to do the port the app to VB.NET and to my biggest surprise. It's been a while that I opened visual studio in VB.NET project. I was surprised to see an already white dashed App.config file so I added my AppSettings section and after 3 hours I still can't get the value of the username using the same ConfigurationManager
Dim username as String = ConfigurationManager.AppSettings("username")
I have included another application configuration app1.config which by the way has generated entries already. I could not get anything with the app1.config either.It also returns Nothing
</sharedListeners>
</system.diagnostics>
</configuration>
I am really perplexed as how a simple reading of configuration file could be this challenging in VB.NET unless I am using the wrong method which I always use in C#.
Kindly point me to whatever I am not doing right.
EDIT
As you can see in the picture below, I have all it needs to work properly.I as expecting to read the setting key from either App.config or app1.config. When I run like shown below the MessageBox is empty
I found the culprit, I needed to right click the generated App.config and choose Include In Project. that's it. it's weird because I never do that in a C# project.

ConfigurationManager.AppSettings in returning null

I am using ConfigurationManager.AppSettings[myKey] to read a value from the app.config file in my windows application, but the value returned is always null, even though the key exists and it has a value, Deas any one know why?
Thanks
One, perhaps easier, alternative is to use a Settings file. This encapsulates the creation and maintenance of App.config values in a designer GUI and generates code for accessing the values.
To add a Settings file, right click your project in VS and click 'Add -> New Item', select 'Settings file' and give it a meaningful name, e.g. MainSettings.settings. You can then add an item, e.g. Foo, specify whether it is application or user-wide, define it's type and a assign it a value. In your code you can retreive the value by simple writing MainSettings.Default.Foo.
After compilation, you can change the value by editing the config file. The setting will appear as follows:-
<applicationSettings>
<YourNamespace.MainSettings>
<setting name="Foo" serializeAs="String">
<value>Bar</value>
</setting>
</YourNamespace.MainSettings>
</applicationSettings>
Hard to say from what you've provided here:
Check your spelling of the value in myKey
Ensure you are looking at the right app.config - if this call is in a referenced library and you're expecting a value to come from the calling project's app.config, but your library has an app.config for some reason it may be causing your problem.
i have two project in my solution first i add app.config file in class library project which all instances is call from console application i added these entries in config file in class lib project
<appSettings>
<add key="userName" value="user2" />
<add key="emilsLimit" value="50" />
</appSettings>
it was throwing null exception when i get these in a class in class library project but when i delete app.config from class Library project and added in Console project it works.Cheers
Note: Class lib project reference is added in console
I was having the same problem, but when I added an empty string ( + "") on the end it picks up the string in the appsettings
for example
string s = ConfigurationManager.AppSettings["myKey"] + "";

Settings.Default.<property> always returns default value instead of value in persistant storage (XML file)

I recently wrote a DLL in C# (.Net 2.0) which contains a class that requires an IP address. A co-worker of mine altered the class to retrieve the IP from a ".dll.config" (XML) file -- This apparently is automatically generated by the "Application Settings" file he created (Settings1.settings). The benefit of this was to allow the end-user to change the IP address in the XML/config file at will.
Unfortunately, when I check his code out of the tree and try to compile (or use) this new code, any application calling this DLL only gets the default value, rather than the value from the file.
The constructor that calls the config file looks like this:
public class form : System.Windows.Forms.Form
{
public form()
{
// This call is required by the Windows Form Designer.
InitializeComponent();
IP = IPAddress.Parse(Settings1.Default.IPAddress);
}
}
I found a reference to this problem on the MSDN forums where a user said:
the 'old' values (the ones you define at development time) are hard coded. If the franework isn't able to access or open the config file it will use the defaults instead. This will always happen if you use settings in a dll.
Does this mean that I cannot store an external value for a DLL in a config file? (My co-worker has somehow made this work...)
Since my framework appears to be unable to access or open the config file, how do I figure out why it's failing? Or even detect when this happens?
Decker: That helps a bit. Unfortunately, I am writing this DLL to a specification, so I don't actually have access to the Application's config file. As you'll note above, my co-worker created a "Settings1.settings" file. I didn't understand this at the time, but it seems now that adding the "1" keeps it out of the settings space of any application that calls it.
I guess what I'm trying to figure out is why the DLL doesn't seem to find the config file sitting next to it in the same directory. Tracing thru the code step-by-step reveals nothing.
As an aside, I can change the "Output Type" of my assembly from "Class Library" to "Windows Application" and add the following lines at the beginning of my DLL code:
[STAThread]
public static void Main(string[] args)
{
System.Windows.Forms.Application.Run(new form());
}
When I run this, it generates a different config file (a ".exe.config") and that one I can alter and have it pull the new data from the file. So I'm a bit confused. Any ideas?
I use this technique all time time. Often I have a library assembly that requires certain settings, and I need them set both by testing projects as well as the primary "executable" assemblies -- be they web projects or Windows service projects.
You're correct in that when you create a settings file for any project, it adds an application config file. The value you enter for any setting is stored in two places -- the config file AND in attributes on the classes created by the settings infrastructure. When a config file is not found, the values embedded in the attributes are used.
Here is a snippet that shows such an attribute:
Here is a snippet that shows the default value of the ConcordanceServicesEndpointName in the generated class:
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("InternalTCP")]
public string ConcordanceServicesEndpointName {
get {
return ((string)(this["ConcordanceServicesEndpointName"]));
}
}
What you want to do is copy the configuration section out of the app.config file from the library assembly project and merge it (carefully) into the applicable web.config or app.config for the main assembly. At runtime, that's the only config file that is used.
Here is an example:
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="LitigationPortal.Documents.BLL.DocumentsBLLSettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<LitigationPortal.Documents.BLL.DocumentsBLLSettings>
<setting name="ConcordanceServicesEndpointName" serializeAs="String">
<value>InternalTCP</value>
</setting>
</KayeScholer.LitigationPortal.Documents.BLL.DocumentsBLLSettings>
</applicationSettings>
You should copy these sections into the "true" config file.
I'm addressing this exact issue in an application I'm in the midst of prototyping. Although Decker's suggestion of hacking the config files together should work I think this is a pretty inconvenient manual hack to perform as part of a build cycle. Instead of that I've decided that the cleanest solution is to just have each library parse its own library.dll.config file. Its still not perfect and it requires some extra boiler-plate code, but it seems to be the only way to get around the byzantine way that .Net handles these app.config files.
I have had this same problem for a long time - it's annoying.
I like the idea of making your own config file and having each DLL parse it, though it still might be easy to miss having to change the config.
One thing I have done in the past to at least make this a little easier is to make sure that any config values that the Setting1.Settings file are invalid.
For instance, I have a class that uses LINQ-To-SQL to talk to the DB. So it has a Setting1.settings file that it stores the connection string to database in. The default value that is entered (upon dragging and dropping the database tables into the designer) is the connection string of the dev database.
Once I have the DBML file created based off of the test database, I can go in and edit the Settings file and type in a database name like "FAKE_DATABASE".
That way, if you use the DLL in another project, and then forget to merge the config files to add in the proper config value for the DLL, at least you'll get an error saying something like "Cannot connect to FAKE_DATABASE".
Of course, if you have to work with the designer again, you'll have to change the value back to the value of your dev database.
Huge pain. They've gotta change this somehow.
Apparently your application is trying to read from the default config file (which is probably the application's config file). To make sure, add the key-value pair in the dll's config file to the application's config file, run the application and see if it is read this time.
I think I just found an explanation of why this isn't working for my DLL and my test application. Here is the concluding exception from some guy's blog:
The fix for this is to either make sure your application and the support assemblies have the same namespace or to make sure you merge the contents of AppName.exe.config and DllName.dll.config (yes when you compile a .dll now it generates this file, however it is ignored if you copy it to the application directory and is not automatically merged)
So either I have to keep the DLL and Application in the same namespace -or- I have to merge the contents of the DLL config file with the Application's config file.
(Doesn't this sort of defeat the purpose of the DLL? I thought a DLL was supposed to be an independent library.)
Perhaps this is why it works for my co-worker. The production application shares the same namespace as the DLL. (My test app clearly does not...)
UPDATE: I just sat down with my co-worker recently and talked about this problem again and it seems that it was never working for him either, but he hadn't realized it because he had set the initial value to be the same as the device we were trying to use. So of course it appeared to work at first, but as soon as we deployed it elsewhere with slightly different settings it was broken again.
I've seen a similar problem when using app.config. Try running your application from the .exe instead of from Visual Studio & see if it then behaves as expected.
It is possible that in your DLL you have the access modifier (for the Settings1.Settings) set to Internal (Friend for VB). Try changing the Access MOdifier to Public and see if that lets your application read/write values from dll's config.
The answer from Howard covers the theory.
One quick and dirty way of solving this is to parse the xml config file manually.
string configFile = Assembly.GetExecutingAssembly().Location + ".config";
XDocument.Load(configFile).Root.Element("appSettings")....
This code project article gives you some code which allows you to use a Class Library app.config file, and read it properly. And still use the Visual Studio GUI to manage the settings.
https://www.codeproject.com/Articles/246201/Settings-in-an-assembly-configuration-file
The mistake I think you all make is that you apparently make referece to the DLL Settings via Settings1.Default.IPAddress while you are simply suppossed to do this Settings1.IPAddress.
The difference is that when you use Settings1.Default.IPAddress the values are gotten from the hardcoded values imbeded in the assembly file (.dll or .exe) as Attribute [global::System.Configuration.DefaultSettingValueAttribute(...)].
While Settings1.IPAddress is the value that is editable in the file .dll.config (XML file)**. so any changes you make to the XML file, it is not reflected in hardcoded default value in the assembly.
Not this:
IP = IPAddress.Parse(Settings1.Default.IPAddress);
But try this:
*IP = IPAddress.Parse(Settings1.IPAddress);

Categories

Resources