Need some clarification about app.config and user.config - c#

So I have been poking around both here on SO and google for the last few days for information about app.config.
I am writing a program that will need to generate SQL scripts using values entered by a user. Originally I was using app.config to store some default values to load into the program when it is first started up. This worked fine until I tried to store the new values back into the app.config file. This is when I found that app.config is read only and I should have been using user.config.
I have several questions that I can't seem to find the answers to:
Is it recommended to use settings.Setting to declare all the values that I want to use app.config? Or is entering them in by hand is enough?
I keep reading about how user.config overrides app.config settings. But when I update my user.config file, the program still reads from the original app.config file
This is from my wrapper class
public NameValueCollection ReadSettings(string sectionName)
{
NameValueCollection scripts = null;
try
{
//read in the current values from the section
scripts = (NameValueCollection)ConfigurationManager.GetSection(sectionName);
if (scripts == null) throw new appConfigException(String.Format("The section {0} does not exists in app.config", sectionName));
}catch (Exception e){
//print out the log file
StreamWriter writer = new StreamWriter(DateTime.Now.ToString("d-MMM-yyyy") + "log.txt");
writer.WriteLine(e.ToString());
writer.Close();
//kill the application process so the user cannot advance further
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
return scripts;
}
is the ConfigurationManager supposed to automatically know to start reading from the user.config? Or do I need to change this section of code to reflect that?

Question 1: It is easier to use Settings.settings instead of creating your own configuration file yourApp.config. Because using the first option you can access your properties just using Properties.Settings.Default.MyProperty and with the app.config file instead you have to deal with ConfigurationManager object, and usually to access a property you need to know the name beforehand and it usually is hardcoded.
Question 2: Yes, you are right the app.config is different from Settings.setting. Because you could even create a new file temp.config which could also be used as a config file for your application.
Final question: Im not sure, but I don't think ConfigurationManager knows anything about that, just parse the app.config file.
Hope it helps.

Related

dont want to overwrite my ini file

I am using ini file to store my configuration in my c# gui.
but when i start my gui again , and save the configuration, the previous saved configuration gets overwritten.
IS there a way to keep on saving configurations ?
You want to use an app.config file instead of your .ini. You access the settings in it using the ConfigurationManager from the System.Configuration namespace. You can even create custom configuration sections by creating classes that inherit from ConfigurationSection. That will give you intellisense support of your config file, as well.
One example of that (it's using asp.net, but it works for any .net code) is here.
Edit: Re-reading your question, I'm unclear on if you're trying to save application settings (app.config), or if you're trying to save session data to disk (saving records or serializing objects). If the former, look at app.config. You can even have multiple items that set the same "settings" but with different values (such as having multiple SQL Connection strings) and then call them by some parameter you obtain from a user.
If you're trying to save session data/state, then you want to serialize your objects- look into serialization/deserialization (many options available there) and the System.IO namespace for persisting to disk.
The only way to prevent overwriting the same file each time is to make the file name unique e.g.
FileName<TimeStamp>.ini
Or
FileName<Guid>.ini
Or you could even do what windows does with duplicate files and check how many already exist and append a new number onto the end e.g.
FileName.ini
FileName1.ini
FileName2.ini
Personally I would go with the timestamp/GUID approach. Here's some example code
class Program
{
static void Main()
{
for (int i = 0; i <= 10; i++)
{
SaveConfiguration();
Thread.Sleep(500);
}
}
private static void SaveConfiguration()
{
string fileName = System.IO.Path.Combine(#"Config\File\Dir", String.Format("Config{0:yyyyMMddHHmmss}.ini", DateTime.UtcNow));
System.IO.File.WriteAllText(fileName, "File contents");
}
}

C# applicationSettings: how to update app.config?

I am using .NET 4.0 and I would like to use the app.config file to store same parameter settings. I do the following. I use the Settings tab in the project properties to create my parameters.
This add the information in the app.config file like this:
<MyApp.Properties.Settings>
<setting name="param1" serializeAs="String">
<value>True</value>
</setting>
<MyApp.Properties.Settings>
In my view model (in my code) I can access to the information in this way:
bool myBool = MyApp.Properties.Default.param1;
When I try to change the value in the config file, I try this:
Properties.Settings.Default.param1 = false;
But this causes an error, that param1 is read-only.
So how can I update my config file from my code?
Here's my function to update or add an entry into the app.config for "applicationSettings" section. There might be a better way, but this works for me. If anyone can suggest a better method please share it, we'll always looking for something better.
static string APPNODE = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Properties.Settings";
static DateTime now = DateTime.Now;
Utilities.UpdateConfig(APPNODE, "lastQueryTime", now.ToString());
static public void UpdateConfig(string section, string key, string value)
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ClientSettingsSection applicationSettingsSection = (ClientSettingsSection)config.SectionGroups["applicationSettings"].Sections[section];
SettingElement element = applicationSettingsSection.Settings.Get(key);
if (null != element)
{
applicationSettingsSection.Settings.Remove(element);
element.Value.ValueXml.InnerXml = value;
applicationSettingsSection.Settings.Add(element);
}
else
{
element = new SettingElement(key, SettingsSerializeAs.String);
element.Value = new SettingValueElement();
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
element.Value.ValueXml = doc.CreateElement("value");
element.Value.ValueXml.InnerXml = value;
applicationSettingsSection.Settings.Add(element);
}
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("applicationSettings");
}
Well, I read the link of Hari Gillala, in which one user suggested to edit directly the app.config file, that is a xml file.
So in project properties-->settings I create the parameters that I need. Then, to load a parameter in code I do the following:
_myViewModelProperty = MyApp.Properties.Settings.Default.MyParam1;
In this way, I can read easily the information of the config parameter. Is typed, so in disign time I can see if the asign is correct or not.
To update de config file, I edit the app.config file with the xml libraries of .NET.
System.Xml.XmlDocument xml = new System.Xml.XmlDocument();
xml.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
System.Xml.XmlNode node;
node = xml.SelectSingleNode("configuration/applicationSettings/MyApp.Properties.Settings/setting[#name='myparam1']");
node.ChildNodes[0].InnerText = myNewValue;
xml.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
In this way, I create a xml document (xml variable) and load the information of the app.config file. Then, I search for the node that I want to update, update its information (InnerText property) and finally I save the changes.
In this way, I can update the app.config. It is what I want, because in a portable application, only one user will use it, and I want that the configuration is applied in any computer in which I run the application.
You should use Properties.Settings to perform this action.
You can look at this documentation for more information.
//modify
Properties.Settings.Default.param1 = false;
//save the setting
Properties.Settings.Default.Save();
Note that if your settings have the Scope of User, which they must be to be writeable, then the properties are saved somewhere else and not in your local config file. See here for the details.
EDIT after discussion in comment and further searches:
My suggestion to achieve the desired result would be to switch to AppSettings.
That is because, after some searches, i found out that appsettings changes the .config file in the Application Data folder (running some tests on my machine confirm that).
Look at comment in the answer to this question .
I am not sure if there is some work around, but if you want your application to have a portable app.config file, i think the only way is to switch to AppSettings which i'm sure can save changes in the app.config found in the program folder.
EDIT 2: Possible solution
I found out a possible solution to make your app portable!
You can change the Provider used by Settings to save the application's settings creating a custom Provider.
The answer to this question provide a link to a code to make applicationsettings portable. I think you give it a try
Mark your setting as usersetting.
Detailed article: http://www.codeproject.com/Articles/25829/User-Settings-Applied

Modify Database connection string of web.config..?

Good day! I would like to ask, if you know how to modify the web.config.. Its located in a different folder.. I tried using this approach, Unfortunately i doesn't work..
// set Path to your config file
System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(sWebConfig);
// open web.config
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
// display message
Console.WriteLine("Updating wizardConnection string.. Please wait for a few minutes..");
// fetch WizardConnection database connection string
var Wizardsection = (ConnectionStringsSection)configuration.GetSection("WizardConnection");
// assign new value to wizardConnection.. Please make sure you have the correct database server. Just update server location, if need
Wizardsection.ConnectionStrings["WizardConnection"].ConnectionString = string.Format(#"server={0};database={1};integrated security=SSPI", sDatabaseServer, sDatabase);
configuration.Save();
Hope to hear from you soon..
Regards,
Link
Instead of updating web.config, you may use different web.config files for different build configurations. For instance, you may setup a new build configuration namely "Staging" and configure it to use a modified config file.
Have a look at Web.Config transformation
Actually what you are doing will change the config file which is copied to folder that contains binary(debug, release or any custom compiler configuration). That is sufficient to change the connection settings of the application. But, if you want to modify the web.config file, it will be nothing but modifying an external file, for which you will need File opertaions.
You should use webconfigurationmanager to open your webconfig.
Try this
var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
config.ConnectionStrings.ConnectionStrings["ConnectString"].ConnectionString = string.Format(#"server={0};database={1};integrated security=SSPI", sDatabaseServer, sDatabase);
config.Save();

Deploy an application's xml file with installer or create it on the fly if it does not exist

I am having an xml file like:
<CurrentProject>
// Elements like
// last opened project file to reopen it when app starts
// and more global project independend settings
</CurrentProject>
Now I asked myself wether I should deliver this xml file with above empty elements with the installer for my app or should I create this file on the fly on application start if it does not exist else read the values from it.
Consider also that the user could delete this file and that should my application not prevent from working anymore.
What is better and why?
UPDATE:
What I did felt ok for me so I post my code here :) It just creates the xml + structure on the fly with some security checks...
public ProjectService(IProjectDataProvider provider)
{
_provider = provider;
string applicationPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
_projectPath = Path.Combine(applicationPath,#"TBM\Settings.XML");
if (!File.Exists(_projectPath))
{
string dirPath = Path.Combine(applicationPath, #"TBM");
if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
using (var stream = File.Create(_projectPath))
{
XElement projectElement = new XElement("Project");
projectElement.Add(new XElement("DatabasePath"));
projectElement.Save(stream, SaveOptions.DisableFormatting);
}
}
}
In a similar scenario, I recently went for creating the initial file on the fly. The main reason I chose this was the fact that I wasn't depending on this file being there and being valid. As this was a file that's often read from/written to, there's a chance that it could get corrupted (e.g. if the power is lost while the file is being written).
In my code I attempted to open this file for reading and then read the data. If anywhere during these steps I encountered an error, I simply recreated the file with default values and displayed a corresponding message to the user.

.NET Exception Handling Application Configuration File

I apologize as this question is somewhat basic; however, after a great deal of searching, I have not found a suitable answer. I am building a windows forms application and need to reference an app.config file for the location to a data file. Before calling
XElement xml = XElement.Load(ConfigurationManager.AppSettings["EntityData"].ToString());
I want to ensure that the app.config file exists. I have tried multiple methods but it seems that it is a lot more work then it should be. For example I have been trying to use the following code to determine the path for the file
Uri uri = new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
string fullConfigurationFilename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(uri.AbsolutePath), configurationFilename);
but I run into issues with spaces in the path. Is there a better way to check for the existence of the app.config, do I even need to check?
Thank you
I don't think you need to verify that the config file exists. The following code should work without exceptions:
string temp = ConfigurationManager.AppSettings["EntityData"];
if (temp != null)
{
XElement xml = XElement.Load(temp);
}
Note that AppSettings will return a string if the key is found, so you don't need to call ToString to convert it. If the key does not exist, you should instead get a null reference that you can test for.
System.Configuration should do all of this work for you. There shouldn't be a need to manually load a config file.

Categories