Updating a config file adds additional config sections - c#

My goal is to programatically update a .config file belonging to another application.
I start off with a simple config file that looks like this...
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Test1" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
I then run my code to update the connection string named Test1 and rename it to Test2...
var configMap = new ExeConfigurationFileMap() { ExeConfigFilename = #"test\app.config" };
var externalConfiguration = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);
externalConfiguration.ConnectionStrings.ConnectionStrings[1].Name = "Test2";
externalConfiguration.Save(ConfigurationSaveMode.Minimal, true);
This saves the configuration file, but now looking at the file you will see some other data has been added to it...
ConfigurationSaveMode.Minimal
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="Test2" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<trust level="Full" />
<webControls clientScriptsLocation="/aspnet_client/{0}/{1}/" />
</system.web>
</configuration>
ConfigurationSaveMode.Modified
Using the Modified setting I get even more "stuff"...
<configuration>
<appSettings />
<configProtectedData />
<system.diagnostics />
<system.windows.forms />
<uri />
<connectionStrings>
<add name="Test2" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.net>
<authenticationModules />
<connectionManagement />
<defaultProxy />
...snip...
What is this data and where has it come from? More importantly how can I stop it from being written into my file?

Try changing the ConfigurationSaveMode from
ConfigurationSaveMode.Minimal
to
ConfigurationSaveMode.Modified
Modified only saves the properties that you have changed.
From MSDN:
Full
Causes all properties to be written to the configuration file. This is useful mostly for creating information configuration files or moving configuration values from one machine to another.
Minimal
Causes only properties that differ from inherited values to be written to the configuration file.
Modified
Causes only modified properties to be written to the configuration file, even when the value is the same as the inherited value.

The way I have solved this was to set the Machine Configuration File to be the same as my EXE Configuration file, this way the .net Configuration object does not see that there is any difference between Machine and EXE when it is saving.
For example:
var fm = new ExeConfigurationFileMap();
fm.MachineConfigFilename = fm.ExeConfigFilename = #"C:\dude.config";
var c = ConfigurationManager.OpenMappedExeConfiguration(fm, ConfigurationUserLevel.None);
// Do Stuff
c.Save(ConfigurationSaveMode.Minimal, true);
This way you should not get the section in your config file upon save.

Related

Can't read connection string from web.config

I have the following in my web.config located at the root of my project:
<configuration>
<connectionStrings>
<clear />
<add name="Default" providerName="System.Data.SqlClient" connectionString="Server=tcp:whoops;Encrypt=True;TrustServerCertificate=False;Connection Timeout=3000;" />
</connectionStrings>
<appSettings>
<add key="ConnectionString" value="test"/>
</appSettings>
....
I read from Startup.cs (this is an asp.net core web app):
string connection = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
However when I break on this, ConfigurationManager.ConnectionStrings and ConfigurationManager.AppSettings are empty (well, the first has some default connection string that is not the one in web.config).
What's going on here?
You will have to migrate the config to the new file appsettings.json
https://learn.microsoft.com/en-us/aspnet/core/migration/configuration?view=aspnetcore-2.1
Not saying this is how you should do it, but you can do the following...
In ASP.Net Core 2.2, you should be able to add an XML configuration to IConfigurationBuilder using
configBuilder.AddXmlFile("app.config");
Contents is pretty much the same as above...
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings configSource="connectionStrings.config" />
<appSettings>
<add key="Test" value="TestValue" />
</appSettings>
</configuration>
You should then be able to access AppSettings/ConnectionStrings using...
ConfigurationManager.ConnectionStrings
ConfigurationManager.AppSettings.AllKeys
{string[1]}
[0]: "Test"
ConfigurationManager.AppSettings.Get("Test")
"TestValue"

Updating .config file with data from the user

I am trying to save some settings to the appSettings section of my configuration file so I may use the data to carry out the processes of the program. On the click of a button I want the data coming from the user to be saved in the config file. The code I am using is:
private void button1_Click(object sender, EventArgs e)
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["key1"].Value = "value1";
config.AppSettings.Settings["key2"].Value = "value2";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
Before the code is executed my app.config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<appSettings>
<add key="roshane" value=""/>
<add key="email" value=""/>
<add key="super" value=""/>
<add key="phone" value=""/>
</appSettings>
<connectionStrings>
<add name="AutoReportEmailerConnectionString"
connectionString="Data Source=roshane\sqlexpress;Initial Catalog=ICR_v5.0;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
After the code is execute the programName.exe.config file is the same as the app.config. Is there something I am missing why the values are not being added to the programName.exe.config file?
config.Save(ConfigurationSaveMode.Modified) works only when you modify an exisint key in other words a key that was in the web config before if you need to actually add key values to the web config just call config.Save() with no parameters
If you want to add new Key to config file, need to add it first in Settings collection:
config.AppSettings.Settings.Add("Key", "Value");
Then call Save method.

Getting configuration values rom XML file located in the same project

I am making a little program to copy pictures form one location to another. The information for the pictures are stored in a database so I need connections string and also I create a txt file with the final output from the operation and I want to store these two values in a App.Config.xml file.
The structure of my project is very simple :
And the XML files itself is :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyDB" connectionString="Data Source=.\\DVSQLEXPRESS08;Initial Catalog=**;Persist Security Info=True;User ID=**;Password=**;MultipleActiveResultSets=True" />
</connectionStrings>
<createResultFile>
<add key="ResultFile" value="C:\Users\dv\Desktop\Leron\PictureStatus.txt"/>
</createResultFile>
</configuration>
I want to use the connectionString and <createResultFile> value in my PictureTransferTool.cs. This is my first time working with XML file and C# (.NET in general) so I want what is the way to retrieve those config values?
You config file must be like below...
Config File :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ResultFile" value="C:\Users\dv\Desktop\Leron\PictureStatus.txt"/>
</appSettings>
<connectionStrings>
<add name="MyDB" connectionString="Data Source=.\\DVSQLEXPRESS08;Initial Catalog=**;Persist Security Info=True;User ID=**;Password=**;MultipleActiveResultSets=True" />
</connectionStrings>
</configuration>
C# :
You can read Connection String like below
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
Console.WriteLine(connectionString);
You can read User Defined Settings like Below
var Resultfile = System.Configuration.ConfigurationManager.AppSettings["ResultFile"];
Console.WriteLine(Resultfile);
The Way I normally do user-defined parameters in my app.config is i put them in the appSettings tab.
<appSettings>
<add key="myStr" value="String Value" />
and then you can access it with
string myStr = System.Configuration.ConfigurationSettings.AppSettings["myStr"];
It works for me.
Linq;
using System.Xml.XPath;
...
var doc = XDocument.Load("test.xml");// You should put the way to your XML
var name = doc.XPathSelectElements("/configuration/connectionStrings/add").Value;
var name = doc.XPathSelectElements("/configuration/createResultFile/add").Value;

update app.config file programmatically with ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

update app.config file programmatically with
Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
this is my xml
<configuration>
<configSections>
<section name="nhibernateSettings" type="ProjectBase.Data.OpenSessionInViewSection, ProjectBase.Data" />
</configSections>
<appSettings>
<add key="NHibernateConfigPath" value="D:\PROJEKTI\crawler\WebCrawlerSuite\ViaMura.Web\NHibernate.config" />
<!--<add key="NHibernateConfigPath" value="C:\_ZAGON\ViaMura\CurrencyApp\at\NHibernate.config" />-->
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
<connectionStrings>
<add name="connectionString" connectionString="Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Viamura_at;Data Source=.\SQL2008" providerName="System.Data.SqlClient" />
<!--<add name="connectionString" connectionString="server=193.37.152.24\SQL2008;User Id=DBUser;password=Lualah8991;database=Viamura_at" providerName="System.Data.SqlClient" />-->
</connectionStrings>
<nhibernateSettings>
<!-- List every session factory that will be needed; transaction management and closing sessions
will be managed with the open-session-in-view module -->
<sessionFactories>
<clearFactories />
<sessionFactory name="WebCrawlerFactory" factoryConfigPath="D:\PROJEKTI\crawler\WebCrawlerSuite\ViaMura.Web\NHibernate.config" isTransactional="true" />
<!--<sessionFactory name="WebCrawlerFactory" factoryConfigPath="C:\_ZAGON\ViaMura\CurrencyApp\at\NHibernate.config" isTransactional="true" />-->
</sessionFactories>
</nhibernateSettings>
how can I programmatically edit WebCrawlerFactory? I am using
Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
You can use the following code:
private void UpdateConfig(string key, string value, string fileName)
{
var configFile = ConfigurationManager.OpenExeConfiguration(fileName);
configFile.AppSettings.Settings[key].Value = value;
configFile.Save();
}
Where: fileName is the full path + application name (c:\project\application.exe)
In your case, change the AppSetting by Sections:
configFile.Sections["nhibernateSettings"]
The ProjectBase.Data.OpenSessionInViewSection indicates that there is already a custom config section defined that will allow access to the config settings. It may, however be protected or internal to NHibernate.
See if you can reference that class to access the settings.
You could also create a custom configuration section yourself, however it would cause NHibernate to be improperly configured since it would not be able to load the config section properly.
see How to: Create Custom Configuration Sections Using ConfigurationSection

Can we declare variables in the 'app.config' file?

I have a form which needs to get connected to SQL Server, and I have a drop down for selecting the list of databases and perform operations like primary key checking, etc.
But presently my connection string looks like this:
SqlConnection sConnection = new SqlConnection("Server=192.168.10.3;DataBase=GoalPlanNew;User Id=gp;Password=gp");
But apart from the given database, I need to take it variable, so that I can connect it to the database I select from the dropdown.
How can I do this?
Hmm you can declare your variables like this
<appSettings>
<add key="SmtpServerHost" value="********" />
<add key="SmtpServerPort" value="25" />
<add key="SmtpServerUserName" value="******" />
<add key="SmtpServerPassword" value="*****" />
</appSettings>
and read like
string smtpHost = ConfigurationManager.AppSettings["SmtpServerHost"];
int smtpPort = Convert.ToInt32(ConfigurationManager.AppSettings["SmtpServerHost"]);
I think he wants a "semi constant":
Web.Config
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings>
<add name="YourName" providerName="System.Data.ProviderName" connectionString="Data Source={0}; Initial Catalog=myDataBase; User Id=myUsername; Password=myPassword;" />
</connectionStrings>
</configuration>
CS file
String Servername = "Test";
String ConnectionString = String.Format(ConfigurationManager.ConnectionStrings["YourName"].ConnectionString, ServerName);
you can use the connectionStrings tag in the app.config configuration. You can add as many as you want (giving them each a separate key) and then retrieve them
example app.config xml (set providerName to a valid provider, for example System.Data.SqlClient, and the appropriate connection string) :
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings>
<clear />
<add name="firstDb"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
<add name="secondDb"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
</configuration>
example on getting them and listing them (in your case, you would create the appropriate items in the dropdown and set the values) :
ConnectionStringSettingsCollection settings =
ConfigurationManager.ConnectionStrings;
if (settings != null)
{
foreach(ConnectionStringSettings cs in settings)
{
Console.WriteLine(cs.Name);
Console.WriteLine(cs.ProviderName);
Console.WriteLine(cs.ConnectionString);
}
}
You could use the AppSettings section. Read here for an example.

Categories