Saving existing file: empty value attribute is removed - c#

I have a config file like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="key1" value="value1" />
<add key="key2" value="" />
...
</appSettings>
...
</configuration>
I read the config, change the value of key1 and save the config
System.Configuration.Configuration appConfig = ConfigurationManager.OpenExeConfiguration(Configuration.ConfigFile.Replace(".config", string.Empty));
appConfig.AppSettings.Settings["key1].Value = "newvalue1";
appConfig.Save(ConfigurationSaveMode.Minimal);
After this I get the following result:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="key1" value="newvalue1" />
<add key="key2"/>
...
</appSettings>
...
</configuration>
Why is the 'empty' value attribute removed for key "key2"?
When I try it with
appConfig.Save(ConfigurationSaveMode.Modified);
, the attribute is not removed. But I want to know why it's removed in the first case?
Thanks

<add key="key2" value="" />
and
<add key="key2" />
are both functionally equal. The value of key2 with or without that tag is a null string variable which is equivalent to the empty string.
Edit to reflect comment: Simply assign key2 the empty string in the same statement.
System.Configuration.Configuration appConfig = ConfigurationManager.OpenExeConfiguration(Configuration.ConfigFile.Replace(".config", string.Empty));
appConfig.AppSettings.Settings["key1"].Value = "newvalue1";
appConfig.AppSettings.Settings["key2"].Value = "";
appConfig.Save(ConfigurationSaveMode.Minimal);
Second Edit for 2nd comment:
Well, you haven't provided enough information then. All of my answers answer your question. The two values from the first answer are functionally equivalent. Therefore, if you wish to see if the "key2" value = "" then you could simply run the following
if(appConfig.AppSettings.Settings["key2"] == null){
//If this hits, that means <add key="key2" value="" />
}
Please research how to ask a good question and adjust your question to reflect what you are really trying to ask.

Related

Why im getting errors on this? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I created a new project added a webbrowser.
Then I went to the file App.config.
There were 3-4 lines there and I changed their content to this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="EnableSqlDependency" value="true" />
<add key="ApplicationId" value=""></add>
<YOUR APP="" ID="" GOES="" HERE="">
" />
<add key="ApplicationUrl" value="" />
<add key="ApiKey" value="" />
<add key="ApplicationSecret" value=""></add><YOUR APP="" SECRET="" GOES="" HERE=""></YOUR>
" />
<add key="ExtendedPermissions" value="offline_access" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>
I'm getting now 3 errors:
Error 1 Application Configuration file "App.config" is invalid. The 'YOUR' start tag on line 6 position 6 does not match the end tag of 'appSettings'. Line 13, position 9.
Error 3 Expecting end tag .
Error 2 Tag was not closed.
How do i fix this erros ? Can someone show me a fixed code according to my App.config code ?
EDIT**
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="EnableSqlDependency" value="true" />
<add key="ApplicationId" value=""></add>
<YOUR APP="" ID="" GOES="" HERE="">
" />
<add key="ApplicationUrl" value="" />
<add key="ApiKey" value="" />
<add key="ApplicationSecret" value=""></add>
</YOUR>
"
<add key="ExtendedPermissions" value="offline_access" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>
Warning 1 The element 'appSettings' has invalid child element 'YOUR'. List of possible elements expected: 'add, remove, clear'.
How do i fix this erros
Remove (or comment) the malformed XML that does not fit the web.config schema:
<!-- <YOUR APP="" ID="" GOES="" HERE="">
" /> -->
Your Config file is mal-formed. Copy below xml and paste-overwrite your current config file.
Then
- Where it says YOUR_APP_ID_GOES_HERE paste the APP_ID code you got from the API Provider / whichever API you are trying to use.
- Where it says YOU_APP_SECRET_GOES_HERE paste the SECRET CODE / KEY you got from the API Provider / whichever API you are trying to use.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="EnableSqlDependency" value="true" />
<add key="ApplicationId" value="YOUR_APP_ID_GOES_HERE"/>
<add key="ApplicationUrl" value="" />
<add key="ApiKey" value="" />
<add key="ApplicationSecret" value="YOU_APP_SECRET_GOES_HERE" />
<add key="ExtendedPermissions" value="offline_access" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>
Final note: You'll need the ApiKey value also set to a valid string, in order to be able to use the API that you are trying to write a client for.

How to use ConfigurationManager.AppSettings with a custom section?

I need to get "http://example.com" from using App.config file.
But at the moment I am using:
string peopleXMLPath = ConfigurationManager.AppSettings["server"];
I cannot get the value.
Could you point out what I am doing wrong?
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<configSections>
<section name="device" type="System.Configuration.SingleTagSectionHandler" />
<section name="server" type="System.Configuration.SingleTagSectionHandler" />
</configSections>
<device id="1" description="petras room" location="" mall="" />
<server url="http://example.com" />
</configuration>
I think you need to get the config section, and access that:
var section = ConfigurationManager.GetSection("server") as NameValueCollection;
var value = section["url"];
And you also need to update your config file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<configSections>
<section name="device" type="System.Configuration.NameValueSectionHandler" />
<section name="server" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<device>
<add key="id" value="1" />
<add key="description" value="petras room" />
<add key="location" value="" />
<add key="mall" value="" />
</device>
<server>
<add key="url" value="http://example.com" />
</server>
</configuration>
Edit: As CodeCaster mentioned in his answer, SingleTagSectionHandler is for internal use only. I think NameValueSectionHandler is the preferred way to define config sections.
The SingleTagSectionHandler documentation says:
This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.
You can retrieve it as a HashTable and access its entries using Configuration.GetSection():
Hashtable serverTag = (Hashtable)ConfigurationManager.GetSection("server");
string serverUrl = (string)serverTag["url"];
string peopleXMLPath = ConfigurationManager.AppSettings["server"];
gets the value from the appSettings part of the app.config file but you are storing your value in
<server url="http://example.com" />
Either put the value in the appSettings section as below or retrieve the value from its current location.
You need to add a key value pair to your config's appSettings section. As below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="server" value="http://example.com" />
</appSettings>
</configuration>
Your reading code is correct but you should probably check for null. If the code fails to read the config value the string variable will be null.
You're defining a configuration section instead of a value in AppSettings. You can simply add your setting to AppSettings:
<appSettings>
... may be some settings here already
<add key="server" value="http://example.com" />
</appSettings>
Custom config sections are typically used for more complicated configurations (e.g. multiple values per key, non-string values, etc.
If you want to get the value from the app settings your appsetting element in configuration file must have a key.
define your sever value as mentioned below under configuration section:
<configuration>
<appSettings>
<add key="server" value="http://example.com" />
</appSettings>
...
...
...
</configuration>
Now execute below code line to get the server url:
string peopleXMLPath = ConfigurationManager.AppSettings["server"].ToString();

How to change the value of attribute in appSettings section with Web.config transformation

Is it possible to transform the following Web.config appSettings file:
<appSettings>
<add key="developmentModeUserId" value="00297022" />
<add key="developmentMode" value="true" />
/* other settings here that should stay */
</appSettings>
into something like this:
<appSettings>
<add key="developmentMode" value="false" />
/* other settings here that should stay */
</appSettings>
So, I need to remove the key developmentModeUserId, and I need to replace the value for the key developmentMode.
You want something like:
<appSettings>
<add key="developmentModeUserId" xdt:Transform="Remove" xdt:Locator="Match(key)"/>
<add key="developmentMode" value="false" xdt:Transform="SetAttributes"
xdt:Locator="Match(key)"/>
</appSettings>
See Also: Web.config Transformation Syntax for Web Application Project Deployment
Replacing all AppSettings
This is the overkill case where you just want to replace an entire section of the web.config. In this case I will replace all AppSettings in the web.config will new settings in web.release.config. This is my baseline web.config appSettings:
<appSettings>
<add key="KeyA" value="ValA"/>
<add key="KeyB" value="ValB"/>
</appSettings>
Now in my web.release.config file, I am going to create a appSettings section except I will include the attribute xdt:Transform=”Replace” since I want to just replace the entire element. I did not have to use xdt:Locator because there is nothing to locate – I just want to wipe the slate clean and replace everything.
<appSettings xdt:Transform="Replace">
<add key="ProdKeyA" value="ProdValA"/>
<add key="ProdKeyB" value="ProdValB"/>
<add key="ProdKeyC" value="ProdValC"/>
</appSettings>
Note that in the web.release.config file my appSettings section has three keys instead of two, and the keys aren’t even the same. Now let’s look at the generated web.config file what happens when we publish:
<appSettings>
<add key="ProdKeyA" value="ProdValA"/>
<add key="ProdKeyB" value="ProdValB"/>
<add key="ProdKeyC" value="ProdValC"/>
</appSettings>
Just as we expected – the web.config appSettings were completely replaced by the values in web.release config. That was easy!
If you want to make transformation your app setting from web config file to web.Release.config,you have to do the following steps.
Let your web.config app setting file is this-
<appSettings>
<add key ="K1" value="Debendra Dash"/>
</appSettings>
Now here is the web.Release.config for the transformation.
<appSettings>
<add key="K1" value="value dynamicly from Realease"
xdt:Transform="SetAttributes"
xdt:Locator="Match(key)"
/>
</appSettings>
This will transform the value of K1 to the new value in realese Mode.
I do not like transformations to have any more info than needed. So instead of restating the keys, I simply state the condition and intention. It is much easier to see the intention when done like this, at least IMO. Also, I try and put all the xdt attributes first to indicate to the reader, these are transformations and not new things being defined.
<appSettings>
<add xdt:Locator="Condition(#key='developmentModeUserId')" xdt:Transform="Remove" />
<add xdt:Locator="Condition(#key='developmentMode')" xdt:Transform="SetAttributes"
value="false"/>
</appSettings>
In the above it is much easier to see that the first one is removing the element. The 2nd one is setting attributes. It will set/replace any attributes you define here. In this case it will simply set value to false.

Reading from a app.config file

I am trying to print to Console.Write the value of the key name from the following app.config file.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="name" value="Chan" />
</appSettings>
</configuration>
C# code :
Console.Write(ConfigurationManager.AppSettings["name"]);
Nothing gets printed in the console. Why is this ?
Note: I have added a reference to the System.Configuration dll
below code gives you the content of active config file.
var content = File.ReadAllLines(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
Check what you get as content, is it contain key="name" value="Chan" or something else
?
if you given <add key="name" value="Chan" /> then
ConfigurationManager.AppSettings["name"] should return as Chan
Given that your XML file (app.config) is properly formatted, try below.
Declare a variable and assign the variable the AppSettings value. Similar like-
string sName = "";
sName = ConfigurationManager.AppSettings["name"].ToString();

create your own settings in xml

I'm in a ASP.NET project where I need to give several parameters to the administrator that is going to install the website, like:
AllowUserToChangePanelLayout
AllowUserToDeleteCompany
etc...
My question is, will be a good thing to add this into the web.config file, using my own configSession or add as a profile varibles? or should I create a XML file for this?
What do you do and what are the cons and favs?
I originally thought about web.config but I then realized that I should mess up with Website configurations and my own web app configuration and that I should create a different file, them I read this post and now I'm on this place... should I do this or that?
I usually use Settings - available via the project properties - Settings. These can be edited and saved in code, and I write a form / web page to edit them.
If you want to use the XML configuration, there's an attribute called file that reads external files.
You could have a web.config file and a someothername.config file. The someothername.config would have settings like:
<appSettings>
<add key="ConnString" value="my conn string" />
<add key="MaxUsers" value="50" />
</appSettings>
And the web.config would have
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="ExternalWeb.config">
<add key="MyKey" value="MyValue" />
</appSettings>
</configuration>
See DevX for the example I stole.
just to let you guys know that I did what configurator recommended but with a twist.
instead of asking all the time (that I need) for
System.Configuration.ConfigurationManager.AppSettings["myKey"];
I just created a static class that would pull this values with what we call by Strongly typed values (so you don't need to remember all the values)
the mySettings class
public static class mySettings
{
public enum SettingsType
{ UserPermitions, WebService, Alerts }
public enum SectionType
{ AllowChangeLayout, AllowUserDelete, MaximumReturnsFromSearch, MaximumOnBatch, SendTo }
public static String GetSettings(SettingsType type, SectionType section)
{
return
ConfigurationManager.AppSettings[
String.Format("{0}_{1}",
Enum.Parse(typeof(SettingsType), type.ToString()).ToString(),
Enum.Parse(typeof(SectionType), section.ToString()).ToString())
];
}
}
the web.config appSettings part
<configuration>
<appSettings file="myApp.config">
<add key="UserPermitions_AllowChangeLayout" value="" />
<add key="UserPermitions_AllowUserDelete" value="" />
<add key="WebService_MaximumReturnsFromSearch" value="" />
<add key="Alerts_SendTo" value="" />
<add key="Alerts_MaximumOnBatch" value="" />
</appSettings>
</configuration>
the entire myApp.config file
<?xml version="1.0" encoding="utf-8" ?>
<!--
###
### This file serves the propose of a quick configuration.
### Administrator can either change this values directly or use the
### Settings tab in the application.
###
-->
<appSettings>
<!-- *** User Access Configuration *** -->
<!-- Allow user to change the panels layout {1: Yes} {0: No} -->
<add key="UserPermitions_AllowChangeLayout" value="1" />
<!-- Allow user to delete a company fro monitoring -->
<add key="UserPermitions_AllowUserDelete" value="1" />
<!-- *** Web Service configuration *** -->
<!-- Maximum responses from the search service -->
<add key="WebService_MaximumReturnsFromSearch" value="10" />
<!-- *** Allerts configuration *** -->
<!-- Send the alerts to the email writeen below -->
<add key="Alerts_SendTo" value="bruno.in.dk#gmail.com" />
<!-- Send an alert when user import more than the number bellow -->
<add key="Alerts_MaximumOnBatch" value="10" />
</appSettings>
So, now I call like this:
p.value = mySettings.GetSettings(
mySettings.SettingsType.WebService,
mySettings.SectionType.MaximumReturnsFromSearch);
Hope that helps someone with the same problem :)
You may also put your configurations in a settings file. In your project, open Properties and go to Settings which looks
like so
To access the values in your code, use Properties.Settings.YourSettingName;
Use Properties.Settings.Default.Reload(); to refresh your settings during runtime

Categories

Resources