How to update App.config using C#3.5 framework? - c#

How to update in C#3.5 app.config file or Settings.settings file through C# code?
Please provide me the code related to C#3.5 framework support of classes but not with 2.0 framework classes in updating app.config file.

I messed with this issue on a project, and decided depending on circumstance to just use a simple XML config file of my own. The problem is app.config has application level and user level settings for a specific reason. The Code Project article mentioned by others here can get you there, but seems like a lot of work to me.
Easy way, create an XML file:
<?xml version="1.0" encoding="utf-8" ?>
<paths>
<path name="pathtofile1">
<fullpath>\\machine1\folder1\file.txt</fullpath>
</path>
<path name="pathtofile2">
<fullpath>\\machine2\folder2\file2.txt</fullpath>
</path>
</paths>
then use LINQ to get at a node:
XDocument doc = XDocument.Load(pathToXmlfile);
var filePath1 = from c in doc.Descendants("path")
where (string)c.Attribute("name") == "pathtofile1"
select (string)c.Element("fullpath").Value;
string thePath = filePath1.First();
Of course you don't have the built in typing, but this is an easy, generic approach you can use in a lot of situations such as in dll classes.
Now that you are using a 'regular' xml file, you can use the techniques mentioned here to update it. For example and this blog does a nice job.

Possible solution: Changing App.config at Runtime

Please check out this code:
You have to load the web.congif first:
System.Configuration.Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
Then you can modify or add it just like this:
if (config.AppSettings.Settings["YourTag"] == null)
{
config.AppSettings.Settings.Add("YourTag", "yourValue");
}
else
{
config.AppSettings.Settings["YourTag"].Value = "yourValue";
}

It's an XML file so you can use LINQ to XML to open the file
var appConfigPath = string.Format("{0}{1}.exe.config", Directory.GetCurrent(), Process.GetCurrentProcess().ProcessName);
var appConfig = XDocument.Parse(appConfigPath);
//have at it

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("..\\App.config");
XmlNode node = xmlDoc.SelectSingleNode("configuration/capabilities/single/add");// pass xpath of node
//node.Attributes[1].Value = MethodBase.GetCurrentMethod().Name;
node.Attributes[1].Value = TestContext.CurrentContext.Test.MethodName;
xmlDoc.Save("..\\App.config");
Please write in main methods, it is working for me.

Related

Insert a node into a XML file

I am trying to add a single line/node (provided below) into an XML:
<Import Project=".www\temp.proj" Condition="Exists('.www\temp.proj')" />
The line could be under the main/root node of the XML:
<Project Sdk="Microsoft.NET.Sdk">
The approach I used:
XmlDocument Proj = new XmlDocument();
Proj.LoadXml(file);
XmlElement root = Proj.DocumentElement;
// Not sure about the next steps
root.SetAttribute("not sure", "not sure", "not sure");
Though I don't exactly know how to add that line in the XML, cause it was my first try on directly editing XML files, the error caused an extra problem over it.
I get this error on my first attempt:
C# "loadxml" 'Data at the root level is invalid. Line 1, position 1.'
Know this error was a famous one, which some provided a variety of approaches in this link:
xml.LoadData - Data at the root level is invalid. Line 1, position 1
Unfortunately, most of the solutions are outdated, the answer didn't work on this case, and I don't know how to apply others on this case.
Provided/accepted answer on the link for that issue:
string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartsWith(_byteOrderMarkUtf8))
{
xml = xml.Remove(0, _byteOrderMarkUtf8.Length);
}
Basically it didn't work, cause xml.StartsWith seems not existing anymore, at the same time xml.Remove also doesn't exist.
Can you please provide a piece of code that bypass the error and add the line to the XML?
Edit:
The sample XML file is provided in the comments section.
For the Xml posted in the comment, I have used two approachs :
1 - XmlDocument
XmlDocument Proj = new XmlDocument();
Proj.Load(file);
XmlElement root = Proj.DocumentElement;
//Create node
XmlNode node = Proj.CreateNode(XmlNodeType.Element, "Import", null);
//create attributes
XmlAttribute attrP = Proj.CreateAttribute("Project");
attrP.Value = ".www\\temp.proj";
XmlAttribute attrC = Proj.CreateAttribute("Condition");
attrC.Value = "Exists('.www\\temp.proj')";
node.Attributes.Append(attrP);
node.Attributes.Append(attrC);
//Get node PropertyGroup, the new node will be inserted before it
XmlNode pG = Proj.SelectSingleNode("/Project/PropertyGroup");
root.InsertBefore(node, pG);
Console.WriteLine(root.OuterXml);
2 - Linq To Xml, by using XDocument
XDocument xDocument = XDocument.Load(file);
xDocument.Root.AddFirst(new XElement("Import",
new XAttribute[]
{
new XAttribute("Project", ".www\\temp.proj"),
new XAttribute("Condition", "Exists('.www\\temp.proj')")
}));
Console.WriteLine(xDocument);
Namespace to add for XDocument:
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
Both solutions give the same result, but the last one is simple.
I hope you find this helpful.
Would it be possible for you to use the official MSBuild libraries?(https://www.nuget.org/packages/Microsoft.Build/)
I'm not sure which nuget package is actually required to read and edit project files only.
I've tried to programatically edit MSBuild project files directly and can not recommend it. It broke regulary due to unexpected changes...
The MSBuild library does a good job in editing project files and e.g. adding Properties, Items or Imports.

Asternet AGI GeneralMappingStrategy using XML

I am trying to use XML for my GeneralMappingStrategy in Asternet. I have my program working fine using List
such as:
agiServer.MappingStrategy = new GeneralMappingStrategy(
new List<ScriptMapping>()
{
new ScriptMapping() {
ScriptName = "testIVR",
ScriptClass = "Asterisk_Test.testIVR",
}
});
But I'd rather have it read an XML file as it says it can do in the documentation, however it does not seem to say anywhere what the XML format is required.
I have tried:
string pathtoxml = "test.xml";
agiServer.MappingStrategy = new GeneralMappingStrategy(pathtoxml);
With my XML as:
<?xml version="1.0"?>
<ScriptMapping>
<ScriptName>testIVR</ScriptName>
<ScriptClass>Asterisk_Test.testIVR</ScriptClass>
</ScriptMapping>
As a complete guess, seemed to make sense, but this won't compile, I get errors of:
System.InvalidOperationException: 'There was an error reflecting type 'System.Collections.Generic.List`1[AsterNET.FastAGI.MappingStrategies.ScriptMapping]'.'
Does anyone happen to know how to do this?
It appears that there was an issue with the Aster.NET library, I've now submitted the fix and it's been accepted. For anyone who has an issue on this in the future, the XML format is:
<?xml version="1.0"?>
<ArrayOfScriptMapping xmlns:xsi="w3.org/2001/XMLSchema-instance"; xmlns:xsd="w3.org/2001/XMLSchema">
<ScriptMapping>
<ScriptName>testIVR</ScriptName>
<ScriptClass>Asterisk_newTest.testIVR</ScriptClass>
</ScriptMapping>
</ArrayOfScriptMapping>

Parsing XFDL Contents - C#

I am tasked with ripping and stripping pertinent data from XFDL files. I am attempting to use XmlDocument's SelectSignleNode method to do so. However, it has proven unsuccessful.
Represntative XML:
<XFDL>
...
<page1>
<check3>true</check3>
</page1>
...
<page sid="PAGE1">
<check sid="CHECK9">
<value>true</value>
</check>
</page>
...
Code:
XmlDocument document = new XmlDocument();
document.Load(memoryStream);//decoded and unzipped xfdl file
//Doesn't work
XmlNode checkBox = document.SelectSingleNode("//check[#sid='CHECK9']/value");
//Doesn't work
XmlNode checkBox = document.SelectSingleNode("//page[#sid='PAGE1']/check[#sid='CHECK9']");
MsgBox(checkBox.InnerXml);
Yields me System.NullReferenceException as an XmlNode isn't selected.
I think I'm having an xpath issue but I can't seem to understand where. The earlier xml node is easily selected using:
XmlNode checkBox = document.SelectSingleNode("//page1/check3");
MsgBox(checkBox.InnerText);
Displays just fine. And just to head it off at the pass, there isn't a definition of <check9></check9> in the <page1> tag.
Anyone have some insight?
Thanks in advance.
Okay, so here's the deal. XFDL defines a default namespace that requires an arbitrary mapping for xpath querying. In my case:
XML:
<XFDL xmlns="http://www.ibm.com/xmlns/prod/xfdl/8.0" ... >
Code:
manager.AddNamespace("a", "http://www.ibm.com/xmlns/prod/xfdl/8.0");
//Append 'a:' to query elements
document.SelectSingleNode("//a:check[#sid='CHECK9']/a:value", manager);
The problem is compounded because <check> is buried in <page> which is defined in another namespace: xfdl. My xpath query becomes:
document.SelectSingleNode("//xfdl:page[#sid='PAGE1']/a:check[#sid='CHECK9']/a:value", manager);
Now this is rather XFDL specific but can be applied to other issues where there are multiple namespaces defined within an XML document.
EDIT 1
Source: http://codeclimber.net.nz/archive/2008/01/09/How-to-query-a-XPath-doc-that-has-a-default.aspx

web.config in asp.net

I've got the function for changing the values in web.config
but my problem is it is not getting the path of web.config correctly and throwing
"Could not find file 'C:\Users\maxnet25\Web.config'"
It was giving error on xmlDoc.Load() function.
My code:
public void UpdateConfigKey(string strKey, string newValue)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config");
if (!ConfigKeyExists(strKey))
{
throw new ArgumentNullException("Key", "<" + strKey + "> not find in the configuration.");
}
XmlNode appSettingsNode = xmlDoc.SelectSingleNode("configuration/appSettings");
foreach (XmlNode childNode in appSettingsNode)
{
if (childNode.Attributes["key"].Value == strKey)
childNode.Attributes["value"].Value = newValue;
}
xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config");
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
Label1 .Text ="Key Upated Successfullly";
}
What error messsage is being given?
Either way, you're not really going about modifying web.config in the right way. You should probably take a look at the System.Configuration.ConfigurationManager class as this provides programmatic access to the web.config file in a structured manner. Note that to access this class you need to add a reference to System.Configuration.dll to your project to bring the ConfigurationManager into scope.
If you look at the example code for the GetSection method, it shows how to create/add settings in the appSettings section of a .net config file, so that example should be enough to get you where you want to go.
If you definately want to use this approach to manipulate your web.config file, I suspect that:
AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config")
is incorrect, based on the path that you've shown in the error message. Try removing the ..\..\ and seeing if that works. AppDomain.CurrentDomain.BaseDirectory should be pointing at the location of your web.config file without modification.
Assuming this is indeed an ASP.NET website, instead of this:
AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config"
Use this:
HttpContext.Current.Server.MapPath("~/Web.config")
On a side note, please be aware that anytime you make a change to web.config, your web application restarts. You might not need to worry about that depending on what your web app does though.
Try using Server.MapPath() to resolve the location of your web.config. If you're in a page, Server is one of the page properties. If not, you can find it in HttpContext.Current.
As an example...
HttpContext.Current.Server.MapPath("~/web.config")
...should return the physical path to the web.config at the top of your web application.
Now, you're probably much better off using the WebConfigurationManager, as shown in this post. The approach is much cleaner, but requires a reference to System.Configuration.
Have you added a web.config to your web site?
You should use either:
System.Configuration.ConfigurationManager
for app.config files, or:
System.Web.Configuration.WebConfigurationManager
for web.config files.
You can actually use System.Configuration.ConfigurationManager with web.config files as well, and to be honest, I'm not actually sure if there's any benefit for using one over the other.
But either way, you should not be using the Xml namespaces and writing/modifying the raw XML.

How to use application config file in C#?

I am trying to use a config file in my C# console application. I created the file within the project by going New --> Application Configuration File, and naming it myProjectName.config. My config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SSDirectory" value="D:\Documents and Settings\****\MyDocuments\****" />
</appSettings>
</configuration>
The code to access it looks like this:
private FileValidateUtil()
{
sSDirFilePath = ConfigurationSettings.AppSettings["SSDirectory"];
if (sSDirFilePath == null)
Console.WriteLine("config file not reading in.");
}
Can anyone lend a hint as to why this is not working? (I am getting the error message.)
Thanks!!
badPanda
You can't change the name from app.config and expect ConfigurationManager to find it without providing it more information. Change the name of myProjectName.config back to app.config, rebuild, and you will see a file in the bin folder called myProjectName.exe.config. Then your call to ConfigurationManager.AppSettings should work correctly.
check the documentation
http://msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx
First off, use ConfigurationManager instead of ConfigurationSettings.
Second, instead of saying "doesn't work", which provides no useful information, tell us what you're seeing. Does it compile? Does it throw an exception at runtime? Does your PC start to smoke and smell like melting plastic?
Try this:
public string GetSSDirectory()
{
string sSDirFilePath = string.Empty;
if (!ConfigurationManager.AppSettings.AllKeys.Contains("SSDirectory"))
{
Console.WriteLine("AppSettings does not contain key \"SSDirectory\"");
}
else
{
sSDirFilePath = ConfigurationManager.AppSettings["SSDirectory"];
Console.WriteLine("AppSettings.SSDirectory = \"" + sSDirFilePath + "\"");
}
return sSDirFilePath;
}

Categories

Resources