I am modifying my MyApp.vhost.exe, and the App.vhost.exe is modified as I can see in the text editor, but when I stop the debug application, the App.config values revert back to what they were before the change. What am I doing wrong or what am I missing?
Configuration exeConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var section = exeConfiguration.GetSection(monitorSectionElementName);
if (section != null)
{
var monitorPathElements = (section as MonitorSection).MonitorPaths;
monitorPathElements[monitorPath].CheckSum = checkSum;
}
exeConfiguration.Save(ConfigurationSaveMode.Full, true);
ConfigurationManager.RefreshSection(monitorSectionElementName);
Related
I have created mvc application.. In that i have write code for update web.config.i.e
try
{
//// Helps to open the Root level web.config file.
Configuration webConfigApp = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
AppSettingsSection objAppsettings = (AppSettingsSection)webConfigApp.GetSection("appSettings");
//Edit
if (objAppsettings != null)
{
////Modifying the AppKey from AppValue to AppValue1
objAppsettings.Settings["DaysToKeepJob"].Value = model.Keepjobsfolders.ToString();
objAppsettings.Settings["DeleteLocalStoreStudies"].Value = model.DeleteLocalStoreStudies.ToString();
objAppsettings.Settings["ManualBurnerNoOfCopies"].Value = model.ManualNumberofCopies.ToString();
objAppsettings.Settings["DefaultBurner"].Value = model.DefaultBurner.ToString();
objAppsettings.Settings["AutoBurnerNoOfCopies"].Value = model.AutoNumberofCopies.ToString();
objAppsettings.Settings["SmartDisk"].Value = model.chkSMARTDisk.ToString();
objAppsettings.Settings["ForcetodefaultTransfer"].Value = model.chkKeepjobsfolders.ToString();
////Save the Modified settings of AppSettings.
webConfigApp.Save();
}
if (diskType.Title != null)
{
var res = DiskTypeSave(diskType);
}
return Json(new { Status = "Success", Msg = "Rules Saved Successfully." }, JsonRequestBehavior.AllowGet);
}
but after this line webConfigApp.Save(); my session i.e Session["UserAccessRights"] get null . i know because of updating web.config it get null.
Please suggest to maintain session even web.config updates
Every time you change the web.config the application is restarted in IIS.
You can do one of the things below :
Use another settings file, a xml, json, etc. to store those values
Use the database to store those settings per user
Use SQL server for saving sessions or a state server, not in-memory (default)
For this you first have to keep Sessions copy into local variable and then assign again. But for this you have to keep Session.SessionId copy also, because on new session it sets again.
I'm working on a windows based project , in this project we used multiple settings files in order to set text of controls for example buttons.settings, lables.settings and .....
now I need to change the content of these settings files with other values at run time, for this reason we created same settings files with same column "Name" but different values, now I really have problem with changing content of these settings files.
I tried to change content of my tow settings file by loading and saving them as xmlDocument, but unfortunately my app.config doesnt change by new values.
I also used ConfigurationManager.RefreshSection ...
plz help me
thnx in advance
I'll start from describing my setup, just to be sure that we are on the same page.
Thats my setting file - Settings1.settings, with just one setting Test, & the default value being DefaultValue
At this point, the default value is also copied to app.config.
Now, I have a template whose settings which shall come into effect at run time, Its in the form of user.config. And this is how it looks like -
here is the code from working experiment -
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(Settings1.Default.Test); // this shows "DefaultValue" in a message box
// Now change the user.config file with our template file -
//1. I get the location of user config
var fileForUser = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
//2. now I'll Place my template file, where user.config should be present
// create directory if it doesnt exist
if(Directory.Exists(Path.GetDirectoryName(fileForUser)) == false)
Directory.CreateDirectory(Path.GetDirectoryName(fileForUser)) ;
// I have kept my template at E:\template.config
File.Copy(#"E:\template.config", fileForUser, true);
MessageBox.Show(Settings1.Default.Test); // this still shows "DefaultValue" because the user.config is not reloaded
//3. Read the new setting
Settings1.Default.Reload();
MessageBox.Show(Settings1.Default.Test); // this shows "Default Value is changed to ABC" because the user.config is now reloaded
}
The App.config remains as it is & incase I delete the user.config or call Settings1.Default.Reset() then its the App.config which provides the application with default values
Hope it helps. Do let me know if it served yr purpose or not.
Update 1 Supporting the already tried approach by author of the question
Here is the working code to support yr approach, which will bring the settings file's setting in applicaion -
regret my typo - Lables2.settings, Lables.settings instead of Labels2.settings & Labels.settings
{
// 1. Open the settings xml file present in the same location
string settingName = "Lables2.SETTINGS"; // Setting file name
XmlDocument docSetting = new XmlDocument();
docSetting.Load(Application.StartupPath + Path.DirectorySeparatorChar + settingName);
XmlNodeList labelSettings = docSetting.GetElementsByTagName("Settings")[0].ChildNodes;
// 2. Open the config file
string configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
XmlDocument appSettingDoc = new XmlDocument();
appSettingDoc.Load(configFile);
XmlNodeList appConfigLabelSettings = appSettingDoc.GetElementsByTagName("userSettings")[0].
SelectNodes("WindowsFormsApplication2.Lables")[0].ChildNodes;
//ProjectName.Setting file
//3. update the config file
for (int i = 0; i < appConfigLabelSettings.Count; i++)
{
var v = appConfigLabelSettings.Item(i).ChildNodes[0];
v.InnerText = labelSettings.Item(i).InnerText;
}
//4. save & load the settings
appSettingDoc.Save(configFile);
Lables.Default.Reload();
MessageBox.Show(Lables.Default.Code); // test pass... shows A2
}
My project settings -
Thats the executable folder, where
And this is how the labels2.settings look like
Update 2 Approach without xml document
All the setup is same & this is much cleaner. Please try -
{
// 1. Open the settings xml file present in the same location
string settingName = "Lables2.SETTINGS"; // Setting file name
XmlDocument docSetting = new XmlDocument();
docSetting.Load(Application.StartupPath + Path.DirectorySeparatorChar + settingName);
XmlNodeList labelSettings = docSetting.GetElementsByTagName("Settings")[0].ChildNodes;
Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A1 GroupB1 NameC1
//2. look for all Lables2 settings in Label settings & update
foreach (XmlNode item in labelSettings)
{
var nameItem = item.Attributes["Name"];
Lables.Default.PropertyValues[nameItem.Value].PropertyValue = item.InnerText;
}
Lables.Default.Save(); // save. this will save it to user.config not app.config but the setting will come in effect in application
Lables.Default.Reload();
Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A2 GroupB2 NameC2
}
Perhaps its the problem with xmlDocument as mentioned here Changing App.config at Runtime
Please keep the setup same as my last response of label.settings & label2.settings.
And try this implementation
{
// 1. Open the settings xml file present in the same location
string settingName = "Lables2.SETTINGS"; // Setting file name
XmlDocument docSetting = new XmlDocument();
docSetting.Load(Application.StartupPath + Path.DirectorySeparatorChar + settingName);
XmlNodeList labelSettings = docSetting.GetElementsByTagName("Settings")[0].ChildNodes;
Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A1 GroupB1 NameC1
//2. look for all Lables2 settings in Label settings & update
foreach (XmlNode item in labelSettings)
{
var nameItem = item.Attributes["Name"];
Lables.Default.PropertyValues[nameItem.Value].PropertyValue = item.InnerText;
}
Lables.Default.Save(); // save. this will save it to user.config not app.config but the setting will come in effect in application
Lables.Default.Reload();
Console.WriteLine("Code {0} Group{1} Name{2}", Lables.Default.Code, Lables.Default.Group, Lables.Default.Name); //prints Code A2 GroupB2 NameC2
}
It works for me, & because its without xmldocument, I'm hopeful it'll work at yr end too. Do let me know the result.
XmlDocument doc = new XmlDocument();
//doc.Load(#"C:\Users\***\Documents\Visual Studio 2008\Projects\ChangingLablesRuntime\ChangingLablesRuntime\_Labels2.settings");
//doc.Save(#"C:\Users\SHYAZDI.IDEALSYSTEM\Documents\Visual Studio 2008\Projects\ChangingLablesRuntime\ChangingLablesRuntime\_Labels.settings");
doc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
var root = doc.GetElementsByTagName("userSettings")[0];
doc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
var Config = System.Configuration.ConfigurationManager.OpenExeConfiguration(#"path of app.config");
var root = doc.GetElementsByTagName("userSettings")[0];
doc.GetElementsByTagName("userSettings")[0].SelectSingleNode("Zeus._Labels").InnerText = doc.GetElementsByTagName("userSettings")[0].SelectSingleNode("ChangingLablesRuntime._Labels2").InnerText;
//var newEml = root.SelectSingleNode("ChangingLablesRuntime._Labels2");
//var oldEml = root.SelectSingleNode("Zeus._Labels");
//oldEml.InnerText = newEml.InnerText;
//oldEml.ParentNode.ReplaceChild(newEml, oldEml);
doc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
Config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("userSettings");
here is my code , lables2 is same as lables1 with different values, after running this code nothing happened.
this is piece of lables1.settings , that I want to replace with lables2.settings:
this is piece of lables2.settings :
and app.config related code :
I am trying to publish to an ftp server. I am encrypting my Web.config file using this code:
var exeConfigName = #"D:\Repo\mypp\WebApplication1\Web.config";
Configuration config = ConfigurationManager.OpenExeConfiguration(exeConfigName);
var section = config.GetSection("appSettings") as AppSettingsSection;
ConnectionStringsSection section2 = config.GetSection("connectionStrings") as ConnectionStringsSection;;
var section3 = config.GetSection("system.net/mailSettings/smtp") as ConfigurationSection;
if (section != null && section.SectionInformation.IsProtected) {
// Remove encryption.
section.SectionInformation.UnprotectSection();
} else {
// Encrypt the section.
if (section != null) section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
}
if (section2 != null && section2.SectionInformation.IsProtected) {
// Remove encryption.
section2.SectionInformation.UnprotectSection();
} else {
// Encrypt the section.
if (section2 != null) section2.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
}
if (section3 != null && section3.SectionInformation.IsProtected) {
// Remove encryption.
section3.SectionInformation.UnprotectSection();
} else {
//Encrypt the section
if (section3 != null) section3.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
}
// Save the current configuration.
config.Save();
I get two webconfigs i.e Web.config(normal) and Web.config.cong(encrypted). When I publish only Web.config is shipped. So I manually added encrypted sections to the Web.config on server. But i get the following error:
Failed to decrypt using provider 'DataProtectionConfigurationProvider'. Error message from the provider: Key not valid for use in specified state.
</runtime>
<appSettings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>//error highlighted in red
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAKvzpAGMd9EWXylxQjNCcdAQAAAACAAAAAAADZgAAwAAAABAAAABPSw54k9XlD+Mv/LWO9npqAAAAAASAAACgAAAAEAAAALpLRoKXjtupmwjCJCBfEtwgAAAAO3J95kdVtev2Cvc1Chtkajg8ZNamBU7zV9EXNy4VQgoUAAAAVNrkN3oVQVy12XSbxdZVVilA/r0=</CipherValue>
How can I fix this. Also i do not have a release folder in my bin folder(weird). This is my first time publishing and doing encryption. Thanks
I have code, including unit tests, that tries to save the config file multiple times. When I try to save the config file a second time I get this error:
Unable to save config to file [FileName]
My code is basically doing this:
{
Configuration config = ConfigurationManager.OpenExeConfiguration(configName);
...change some values...
config.save();
}
and then again later
{
Configuration config = ConfigurationManager.OpenExeConfiguration(configName);
...change some values in a different way...
config.save();
}
When I execute the config.save for the second time, there is a 10 second delay, and then I get the error. Does anyone know how to 'unlock' this file?
I tried keeping the instance of the config variable, i.e. 'in-scope' but that did not work.
private static Configuration GetConfiguration(string configName)
{
Configuration retval;
if (_configs == null) _configs = new Dictionary<string, Configuration>();
if (_configs.TryGetValue(configName, out retval)) return retval;
retval = ConfigurationManager.OpenExeConfiguration(configName);
_configs.Add(configName, retval);
return retval;
}
and then
{
Configuration config = GetConfiguration(configName);
...change some values...
config.save();
}
along with
{
Configuration config = GetConfiguration(configName);
...change some values in a different way...
config.save();
}
Ug. I was causing the problem elsewhere in my code.
I had a function like this:
private bool FileHasString(string filename, string searchString)
{
string content = (new StreamReader(filename)).ReadToEnd();
return content.IndexOf(searchString) > 0;
}
I assumed that when the stream reader left scope, that the lock on the file ended. The lock apparently did not, and that what was causing the trouble.
This works much better.
private bool FileHasString(string filename, string searchString)
{
var sr = new StreamReader(filename);
string content = sr.ReadToEnd();
sr.Close();
return content.IndexOf(searchString) > 0;
}
Thanks for the help.
Can you keep config in scope between these two code blocks, so you don't have to load it a second time?
The logic behind ConfigurationManager and the System.Configuration namespace is actually quite complex, because the configuration it produces isn't from just one file, even when you are specifically asking for the EXE config. It's possible, for instance, for the user.config to be corrupted, which prevents loading the entire EXE config. I've seen that happen more times than I can count, and the best fix I know of is just to blow away the user config and start over. Similarly, it's possible that the user.config is locked because ConfigurationManager itself is doing something to it.
How can I modify / manipulate the web.config programmatically with C# ? Can I use a configuration object, and, if yes, how can I load the web.config into a configuration object ? I would like to have a full example changing the connection string. After the modification the web.config should be written back to the harddisk.
Here it is some code:
var configuration = WebConfigurationManager.OpenWebConfiguration("~");
var section = (ConnectionStringsSection)configuration.GetSection("connectionStrings");
section.ConnectionStrings["MyConnectionString"].ConnectionString = "Data Source=...";
configuration.Save();
See more examples in this article, you may need to take a look to impersonation.
Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
ConnectionStringsSection section = config.GetSection("connectionStrings") as ConnectionStringsSection;
//section.SectionInformation.UnprotectSection();
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
config.Save();
Since web.config file is xml file you can open web.config using xmldocument class. Get the node from that xml file that you want to update and then save xml file.
here is URL that explains in more detail how you can update web.config file programmatically.
http://patelshailesh.com/index.php/update-web-config-programmatically
Note: if you make any changes to web.config, ASP.NET detects that changes and it will reload your application(recycle application pool) and effect of that is data kept in Session, Application, and Cache will be lost (assuming session state is InProc and not using a state server or database).
This is a method that I use to update AppSettings, works for both web and desktop applications. If you need to edit connectionStrings you can get that value from System.Configuration.ConnectionStringSettings config = configFile.ConnectionStrings.ConnectionStrings["YourConnectionStringName"]; and then set a new value with config.ConnectionString = "your connection string";. Note that if you have any comments in the connectionStrings section in Web.Config these will be removed.
private void UpdateAppSettings(string key, string value)
{
System.Configuration.Configuration configFile = null;
if (System.Web.HttpContext.Current != null)
{
configFile =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
}
else
{
configFile =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
}
var settings = configFile.AppSettings.Settings;
if (settings[key] == null)
{
settings.Add(key, value);
}
else
{
settings[key].Value = value;
}
configFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
}