Why are my application settings retrieving different values to the ones I expect? - app-config

I have inherited an application which uses the configuration manager class to store and retrieve settings. In the app.config class there is custom section group "userSettings" which includes a "Server" property.
In the app.config file this value is defined as "a14". In Settings.Designer.vb the default is specified as "a5" yet when I try to access My.Settings.Server it brings back the value "a10", which is a value I previously used in the app.config file.
Not having much experience with the configuration manager, I am at a loss to determine where it is retrieving this value from and what I need to change so that it retrieves the correct server value.
For brevity, I have removed other settings from the code sample.
app.config:
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="WorkstationApp.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
...
<userSettings>
<WorkstationApp.My.MySettings>
<setting name="Server" serializeAs="String">
<value>a14</value>
</setting>
</WorkstationApp.My.MySettings>
</userSettings>
Settings.Designer.vb:
<Global.System.Configuration.UserScopedSettingAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Configuration.DefaultSettingValueAttribute("a5")> _
Public Property Server() As String
Get
Return CType(Me("Server"),String)
End Get
Set
Me("Server") = value
End Set
End Property
Application code: (server is being set to "a10", but I want it to have the app.config value of "a14").
Dim Server As String = My.Settings.Server

It looks like I was expecting the wrong thing (well duh). I had these settings set as User settings, which are stored in the /appdata/ folder and had nothing to do with the app.config file at all.
The user config file had been set with the initial values and had never been modified subsequently with a My.Settings.Save. More details in this answer: Where are My.Settings saved in VB 2010 .NET?

Related

Where are the settings saved in a .NET 5 WinForms app?

In a .NET Framework WinForms project, there was an App.config file in the project, which was an XML file that contained a configSection that would reference a class in System.Configuration, and a section for the userSettings themselves, like so:
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561944e089">
<section name="MyAppName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561944e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<MyAppName.Properties.Settings>
<setting name="Test" serializeAs="String">
<value>Some Value</value>
</setting>
</MyAppName.Properties.Settings>
</userSettings>
And this created a file in the build folder with the app name plus .exe.config, as in MyAppName.exe.config.
But when I create a new WinForms project using .NET:
There is no App.config in the solution. I can edit the settings using the project properties:
And I can access these values, and update them using the same Properties object and methods:
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
textBox1.Text = Properties.Settings.Default.Test;
}
private void button1_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Test = textBox1.Text;
Properties.Settings.Default.Save();
}
}
}
And everything seems to work, but when I examine the bin folder, there is no file that I can see for where the values are actually stored.
Where is .NET 5 storing the saved application settings if not in a file in the same folder as the application's exe?
User settings are stored in user.config file in the following path:
%userprofile%\appdata\local\<Application name>\<Application uri hash>\<Application version>
Application settings file are not created by default (unexpectedly), however if you create them manually beside the dll/exe file of your application, the configuration system respect to it. The file name should be <Application name>.dll.config. Pay attention to the file extension which is .dll.config.
You may want to take a look at the source code of the following classes:
LocalFileSettingsProvider (The default setting provider)
ClientSettingsStore
ConfigurationManagerInternal
ClientConfigurationPaths
At the time of writing this answer Application Settings for Windows Forms still doesn't have any entry for .NET 5 and redirects to 4.x documentations.
First of all, this is a known (to .NET team) issue: https://github.com/dotnet/project-system/issues/7772.
Secondly the issue and the solution are pretty much described in your question:
(before) ..there was an App.config file in the project,..
(now) There is no App.config in the solution...
Add the missing app.config and everything will work just like it did before.

How do I read a custom section in app.config from codebehind?

I have an app.config file that stores values in a few different sections. I have these snippets:
<configuration>
<configSections>
<sectionGroup name="someDataAccessLayer">
<section name="databaseConnectionStrings" type="sometype" />
</sectionGroup>
</configSections>
<someDataAccessLayer>
<databaseConnectionStrings>
<databaseConnectionString name="someSQL"
value="database=somedatabase;Integrated Security=False;User Id=sa;server=someserver;Password=somepassword/>
</databaseConnectionStrings>
</someDataAccessLayer>
How do I read the connection string in the codebehind? Specifically the value which is
database=somedatabase;Integrated Security=False;User Id=sa;server=someserver;Password=somepassword
Thanks for your help! Please let me know if the question is still unclear.
Your configuration section will be associated with some .NET class to handle it:
<configSections>
<sectionGroup name="someDataAccessLayer">
<section name="databaseConnectionStrings" type="sometype" />
</sectionGroup>
</configSections>
So to read the settings from the <localeSettings> section, you need to use the ConfigurationManager (add a reference to System.Configuration to your project) to get those settings into an instance of that class:
sometype cs = ConfigurationManager.GetSection("someDataAccessLayer/databaseConnectionStrings") as sometype;
Now you have an object of type sometype that contains all the settings in that config section. One of those properties will be a list of database connection strings, which you can now enumerate and find the appropriate one and read it's .Value property.
App.Config Settings:
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="MyApp.LocalConnectionString"
connectionString="Data Source= .\SQLEXPRESS;Initial Catalog=DBName;Integrated Security = true"
providerName="System.Data.SqlClient" />
Access at DataLayer using the ConfigurationManager as:
// add reference
using System.Configuration;
// then access connection string in your class
private static string strConnectionString = ConfigurationManager.ConnectionStrings["MyApp.LocalConnectionString"].ConnectionString;

System.DirectoryServices compilation problems

I'm using the code here : ASP.NET How to get List of Groups in Active Directory
Specifically :
using System.DirectoryServices;
DirectoryEntry objADAM = default(DirectoryEntry); //compiler error!
Problem: compiler says that it doesn't know what DirectoryEntry is.
I tried to add it to my web.config:
<assemblies>
<!-- ... -->
<add assembly="System.DirectoryServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
But it didn't seem to help so I tried to add a reference:
Someone suggested setting Copy Local = True but that didn't help either.
I noticed that I don't see a reference for System.DirectoryServices - only System.DirectoryServices.Accountmanagement
Can anyone help me get this code to compile? I'm not sure what to try next.
Take the .net 3.5 filter off in the Add Reference dialog, and then put a reference in your project to:
System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
You can take the filter off by changing you project setting : http://msdn.microsoft.com/en-us/library/bb398202.aspx
If you want to use the DirectoryEntry from the System.DirectoryServices namespace - you need to add a reference to the System.DirectoryServices assembly - NOT the System.DirectoryServices.AccountManagement assembly!

how to use an external configuration file with WPF?

i would like to set up an external configuration file that I can store in a directory for my WPF app, not necessarily the directory of my exe when I create my program either.
I created an App.Config file and added System.Configuration to my assembly. My App.Config has:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="sd.config">
<add key="username" value="joesmith" />
</appSettings>
</configuration>
and my sd.config (external file) which is in the root of my project for now, has
<?xml version="1.0"?>
<appSettings>
<add key="username1" value="janedoe" />
</appSettings>
in my MainWindow cs class I used
string username = ConfigurationManager.AppSettings.Get("username1");
which returns a null string. when i just retrieve the username field from App.Config it works. What did i miss? Thanks so much!
See the documentation on ConfigurationManager:
The AppSettings property:
Gets the AppSettingsSection data for the current application's default
configuration.
You need to do a little extra work to get data that isn't in your application's default configuration file.
Instead of using the file= attribute, add a key to your <appSettings> that defines the location of the secondary config file, like so:
<add key="configFile" value="sd.config"/>
Then, in order to use ConfigurationManager to pull settings from the secondary config file, you need to use its OpenMappedExeConfiguration method, which should look a little something like this:
var map = new ExeConfigurationFileMap();
map.ExeConfigFilename = Path.Combine(
AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
ConfigurationManager.AppSettings["configFile"]
);
//Once you have a Configuration reference to the secondary config file,
//you can access its appSettings collection:
var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
var userName1 = config.AppSettings["username1"];
That code might not be dead-on for your example, but hopefully it gets you on the right track!

wpf & validation application block > message localization > messageTemplateResource Name&Type

I'm trying to write validation rules for my data objects in a WPF application. I'm writing them in the configuration file, and so far they are working fine.
I'm stumped on how to localize the messages using messageTemplateResourceName and messageTemplateResourceType. What I know is that the strings can be writen in a resource file, given a name and referenced by that name. I get the idea, but i haven't been able to make this work.
<ruleset name="Rule Set">
<properties>
<property name="StringValue">
<validator lowerBound="0" lowerBoundType="Ignore" upperBound="25"
upperBoundType="Inclusive" negated="false" messageTemplate=""
messageTemplateResourceName="msg1" messageTemplateResourceType="Resources"
tag=""
type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation"
name="String Length Validator" />
</property>
</properties>
</ruleset>
Where is the resource file and what value do I pass to messageTemplateResourceType?
I have tried writing the messages in the shell project's resource file but no sucess trying to retrieve the value. I only get the default built-in message.
I've tried
messageTemplateResourceType="typeof(Resources)"
messageTemplateResourceType="Resources"
messageTemplateResourceType="Resources.resx"
messageTemplateResourceType="typeof(Shell)"
messageTemplateResourceType="Shell"
messageTemplateResourceType="Shell,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null"
I've also tried adding a new resource file in the shell project, and adding a resource file to the data object's library. I'm all out of ideas Does anyone have any suggestions? I'm not even married to the idea of resource files, so if there are other ways to localize these messages I'd love to know!
thanks
You need to create your own resource file and then point the messageTemplateResourceType attribute to your fully qualified resource type. As long as the resource file can be loaded at runtime you should be fine.
<ruleset name="Rule Set">
...
messageTemplateResourceName="msg1"
messageTemplateResourceType="My.Fully.Qualified.ResourceType, My.AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
...
</ruleset>
An alternate way to do it would be use the messageTemplate as a key and write custom code to look up the actual localized string based on the messageTemplate key (either from a resource file or from a database or wherever else you are storing it).

Resources