can't get two connecting strings from XML (web.config) - c#

XmlTextReader reader = new XmlTextReader(Window1.cfg.FSAddress);
bool[] startreading = {false , false};
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // Узел является элементом.
if (startreading[0])
{
if (reader.Name == "add")
if (startreading[1])
{
id2.Text = reader.GetAttribute(1);
return;
}
else
{
id1.Text = reader.GetAttribute(1);
startreading[1] = true;
startreading[0] = false;
}
}
else
if (reader.Name == "connectionStrings")
startreading[0] = true;
break;
case XmlNodeType.EndElement:
if (startreading[1])
if (reader.Name == "add")
startreading[0] = true;
break;
}
}
I take first one but ... then happens something strange and I'm missing second
sorry for my english . btw - Im getting it not from web project.

Why would you use SAX-based approach for reading configuration files? These are usually negligibly small, so loading entire document into an XmlDocument and then traversing it using XPath will be a much better solution.

You can use ConfigurationManager.ConnectionStrings to read the connection strings from the connection string section of your web.config file.
Or you can use ConfigurationManager.GetSection to get a section from the config file. If it is a predefined section you can cast it to this type, or you can implement your own custom section (see System.Configuration.ConfigurationSection for a sample).
Oh yes ... you have to include the System.Configuration into your references to work with these classes.

Why try so hard?
Use this:
ConfigurationManager.ConnectionStrings
Which is a collection of ConnectionStrings
Use ConfigurationManager.ConnectionStrings['nameOfTheConnectionString'].ConnectionString() to access the string itself.
ConfigurationManager lives in the System.Configuration namespace

I can't tell what you're trying to do. But maybe XPath will be a lot easier than SAX.

Related

Function for downloading and reading xml file from web stopped working suddenly

I've used this exact code (below) for many years and with existing ISP. I just checked to see if it worked - and it no longer allows me to download the xml file. I get several exceptions when trying to get the Stream object (as shown below). If I put the same URL into the web browser, provide the same credentials, it works fine to download the xml file. So I am not sure why it won't work in this code anymore. Nothing has changed in the code or in credentials, or xml file. The username and password have not changed. I even tried using the domain name in the credentials in the code (although is not required in web browser).
Below code for passing credentials if asked for
Create a resolver with the necessary credentials.
XmlUrlResolver resolver = new XmlUrlResolver();
//try username with and without domain name
// NetworkCredential nc = new NetworkCredential("userxyz#mydomain.com", "password1234");
NetworkCredential nc = new NetworkCredential("userxyz", "password1234");
resolver.Credentials = nc;
// Get a Stream object containing the XML file.
Uri updateXmlUrl = new Uri(UpdateCheckXmlFileUrl);
Stream Updatestream = (Stream)resolver.GetEntity(updateXmlUrl, null, typeof(Stream));
// Construct a reader using the Stream object.
XmlTextReader reader = new XmlTextReader(Updatestream);
Exception error getting stream object
I even tried using new credentials, that perhaps the old ones expire.
Still using .net 4.5 (Visual Studio 2010)
Watch list on next line below
The remaining part of the code is to parse the file read.
//then it suppose to read the XML code from the reader below
reader.MoveToContent();
string elementName = "";
Version newVer = null;
string url = "";
string msiUrl = "";
if (StopWorkerThread()) return;
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "appinfo"))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element) elementName = reader.Name;
else
{
if ((reader.NodeType == XmlNodeType.Text) && (reader.HasValue))
{
switch (elementName)
{
case "version":
newVer = new Version(reader.Value);
break;
case "url":
url = reader.Value;
break;
case "installer":
msiUrl = reader.Value;
break;
case "date":
//elementName = elementName;
break;
}
}
}
}
}
// it gets to here and falls through to a false on the versioninfo.Error
reader.Close();
versionInfo.Error = false;
versionInfo.LatestVersion = newVer;
versionInfo.HomeUrl = url;
versionInfo.InstallerUrl = msiUrl;
As it turns out, I switched to a different hosting site, and the function works correctly. There seems to be some new security imposed on the original hosting site that kept this from reading the xml file. Odd thing is that I could download using http with a web browser, but not with this function. On the new hosting site, both work.

Determine if XmlTextReader.Read() reads an end tag

Using XmlTextReader.Read(), how do I determine if what the reader read is an end/closing tag?
Note that I'm not looking for the usage of XmlTextReader.IsEmptyElement. I'm looking to verify whether given the following XML:
<thistag what="nothing">
<inside color="cyan"/>
</thistag>
Can I determine if the thistag tag I read is an opening tag or a end/closing tag?
My solution so far involved checking for the presence of the what attribute:
if (reader.GetAttribute("what") == null)
{
// it's an end tag!
}else{
// it's a start tag!
}
But I understand that this approach isn't so elegant, and that it could fail if attributes aren't required for that specific tag.
I haven't tried this, hope this helps:
XmlTextReader reader = null;
reader = new XmlTextReader(filename);
while (reader.Read())
{
if(reader.NodeType==XmlNodeType.Element) // for opening tag
{
//your code
}
else if(reader.NodeType==XmlNodeType.EndElement) // for closing tag
{
//your code
}
}
XmlNodeType.Element corresponds to opening nodes. XmlNodeType.EndElement is for closing nodes.

How do I read the summary out of an XML file

I want to get the comments of the xml file for the .dll file.
I am building an proxy class creator (reads an .dll (by Reflection) with interfaces in it --> implements interfaces) and now I thought it would be nice to have the headers of the methods and parameters of the interfaces, but I don't know how.
Thank you for your Answers and pardon my bad english and poor coding knowledge.
I found a Solution:
private static void ReadTheSummarys()
{
XmlReader xmlReader = XmlReader.Create("Test.xml");
bool isSummary = false;
while (xmlReader.Read())
{
//checks if the current node is a summaray
if (xmlReader.Name == "summary")
{
isSummary = true;
continue;
}
if (isSummary)
{
//Replace and trim for pure Comments without spaces and linefeeds
string summary = xmlReader.Value.Trim().Replace("\n", string.Empty);
if (summary != string.Empty)
{
//Writes the pure comment for checking
Console.WriteLine(summary);
}
isSummary = false;
}
}
}

C# .NET XMLWriter/Reader problem

I've been having problems writing XML and reading it in. I have a handwritten XML that gets read in fine, but after I write the XML it acts funny.
The output of the WriteXML: http://www.craigmouser.com/random/test.xml
It works if you hit enter after the (specials) tag. I.E. make (specials)(special) look like
(specials)
(special)
If I step through it, when reading it, it goes to the start node of specials, then the next iteration reads it as an EndElement with name Shots. I have no idea where to go from here. Thanks in advance.
Code: Writing
public void SaveXMLFile(string filename, Bar b, Boolean saveOldData)
{
XmlWriter xml;
if(filename.Contains(".xml"))
{
xml = XmlWriter.Create(filename);
}
else
{
xml = XmlWriter.Create(filename + ".xml");
}
xml.WriteStartElement("AggievilleBar");
xml.WriteElementString("name", b.Name);
xml.WriteStartElement("picture");
xml.WriteAttributeString("version", b.PictureVersion.ToString());
xml.WriteEndElement();
xml.WriteElementString("location", b.Location.Replace(Environment.NewLine, "\n"));
xml.WriteElementString("news", b.News.Replace(Environment.NewLine, "\n"));
xml.WriteElementString("description", b.Description.Replace(Environment.NewLine, "\n"));
xml.WriteStartElement("specials");
xml.WriteString("\n"); //This line fixes the problem... ?!?!
foreach (Special s in b.Specials)
{
if (s.DayOfWeek > 0 || (s.DayOfWeek == -1
&& ((s.Date.CompareTo(DateTime.Today) < 0 && saveOldData )
|| s.Date.CompareTo(DateTime.Today) >= 0)))
{
xml.WriteStartElement("special");
xml.WriteAttributeString("dayofweek", s.DayOfWeek.ToString());
if (s.DayOfWeek == -1)
xml.WriteAttributeString("date", s.Date.ToString("yyyy-MM-dd"));
xml.WriteAttributeString("price", s.Price.ToString());
xml.WriteString(s.Name);
xml.WriteEndElement();
}
}
xml.WriteEndElement();
xml.WriteEndElement();
xml.Close();
}
Code: Reading
public Bar LoadXMLFile(string filename)
{
List<Special> specials = new List<Special>();
XmlReader xml;
try
{
xml = XmlReader.Create(filename);
}
catch (Exception)
{
MessageBox.Show("Unable to open file. If you get this error upon opening the program, we failed to pull down your current data. You will most likely be unable to save, but you are free to try. If this problem persists please contact us at pulsarproductionssupport#gmail.com",
"Error Opening File", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
Bar current = new Bar();
Special s = new Special();
while (xml.Read())
{
if (xml.IsStartElement())
{
switch (xml.Name)
{
case "AggievilleBar":
current = new Bar();
break;
case "name":
if (xml.Read())
current.Name = xml.Value.Trim();
break;
case "picture":
if (xml.HasAttributes)
{
try
{
current.PictureVersion = Int32.Parse(xml.GetAttribute("version"));
}
catch (Exception)
{
MessageBox.Show("Error reading in the Picture Version Number.","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
break;
case "location":
if (xml.Read())
current.Location = xml.Value.Trim();
break;
case "news":
if (xml.Read())
current.News = xml.Value.Trim();
break;
case "description":
if (xml.Read())
current.Description = xml.Value.Trim();
break;
case "specials":
if (xml.Read())
specials = new List<Special>();
break;
case "special":
s = new Special();
if (xml.HasAttributes)
{
try
{
s.DayOfWeek = Int32.Parse(xml.GetAttribute(0));
if (s.DayOfWeek == -1)
{
s.Date = DateTime.Parse(xml.GetAttribute(1));
s.Price = Int32.Parse(xml.GetAttribute(2));
}
else
s.Price = Int32.Parse(xml.GetAttribute(1));
}
catch (Exception)
{
MessageBox.Show("Error reading in a special.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
if (xml.Read())
s.Name = xml.Value.Trim();
break;
}
}
else
{
switch (xml.Name)
{
case "AggievilleBar":
xml.Close();
break;
case "special":
specials.Add(s);
break;
case "specials":
current.Specials = specials;
break;
}
}
}
return current;
}
Without seeing your code it's hard to really give a straight answer to that question. However, I can suggest using Linq-to-XML instead of XMLReader/XMLWriter -- it's so much easier to work with when you don't have to read each node one at a time and determine what node you're working with, which sounds like the problem you're having.
For example, code like:
using (var reader = new XmlReader(...))
{
while reader.Read()
{
if (reader.Name = "book" && reader.IsStartElement)
{
// endless, confusing nesting!!!
}
}
}
Becomes:
var elem = doc.Descendants("book").Descendants("title")
.Where(c => c.Attribute("name").Value == "C# Basics")
.FirstOrDefault();
For an introduction to LINQ-to-XML, check out http://www.c-sharpcorner.com/UploadFile/shakthee/2868/, or just search for "Linq-to-XML". Plenty of examples out there.
Edit: I tried your code and I was able to reproduce your problem. It seems that without a newline before the special tag, the first special element is read in as IsStartElement() == false. I wasn't sure why this is; even skimmed through the XML Specifications and didn't see any requirements about newlines before elements.
I rewrote your code in Linq-to-XML and it worked fine without any newlines:
var xdoc = XDocument.Load(filename);
var barElement = xdoc.Element("AggievilleBar");
var specialElements = barElement.Descendants("special").ToList();
var specials = new List<Special>();
specialElements.ForEach(s =>
{
var dayOfWeek = Convert.ToInt32(s.Attribute("dayofweek").Value);
var price = Convert.ToInt32(s.Attribute("price").Value);
var date = s.Attribute("date");
specials.Add(new Special
{
Name = s.Value,
DayOfWeek = dayOfWeek,
Price = price,
Date = date != null ? DateTime.Parse(date.Value) : DateTime.MinValue
});
});
var bar = new Bar() {
Name = barElement.Element("name").Value,
PictureVersion = Convert.ToInt32(barElement.Elements("picture").Single()
.Attribute("version").Value),
Location = barElement.Element("location").Value,
Description = barElement.Element("description").Value,
News = barElement.Element("news").Value,
Specials = specials
};
return bar;
Would you consider using Linq-to-XML instead of XMLReader? I've had my share of trouble with XMLReader in the past and once I switched to Linq-to-XML haven't looked back!
EDIT: I know this question is rather old now, but I just came across an article that reminded me of this question and might explain why this is happening: --> http://www.codeproject.com/KB/dotnet/pitfalls_xml_4_0.aspx
The author states:
In this light, a nasty difference between XmlReaders/Writers and XDocument is the way whitespace is treated. (See http://msdn.microsoft.com/en-us/library/bb387014.aspx.)
From msdn:
In most cases, if the method takes LoadOptions as an argument, you can optionally preserve insignificant white space as text nodes in the XML tree. However, if the method is loading the XML from an XmlReader, then the XmlReader determines whether white space will be preserved or not. Setting PreserveWhitespace will have no effect.
So perhaps, since you're loading using an XmlReader, the XmlReader is making the determination as to whether or not it should preserve white space. Most likely it IS preserving the white space which is why the newline (or lack thereof) makes a difference. And it doesn't seem like you can do anything to change it, so long as you're using an XmlReader! Very peculiar.
I'd recommend you use the XmlDocument class and its Load and Save methods, and then work with the XML tree instead of messing around with XmlReader and XmlWriter. In my experience using XmlDocument has fewer weird formatting problems.

Can ConfigurationManager retain XML comments on Save()?

I've written a small utility that allows me to change a simple AppSetting for another application's App.config file, and then save the changes:
//save a backup copy first.
var cfg = ConfigurationManager.OpenExeConfiguration(pathToExeFile);
cfg.SaveAs(cfg.FilePath + "." + DateTime.Now.ToFileTime() + ".bak");
//reopen the original config again and update it.
cfg = ConfigurationManager.OpenExeConfiguration(pathToExeFile);
var setting = cfg.AppSettings.Settings[keyName];
setting.Value = newValue;
//save the changed configuration.
cfg.Save(ConfigurationSaveMode.Full);
This works well, except for one side effect. The newly saved .config file loses all the original XML comments, but only within the AppSettings area. Is it possible to to retain XML comments from the original configuration file AppSettings area?
Here's a pastebin of the full source if you'd like to quickly compile and run it.
I jumped into Reflector.Net and looked at the decompiled source for this class. The short answer is no, it will not retain the comments. The way Microsoft wrote the class is to generate an XML document from the properties on the configuration class. Since the comments don't show up in the configuration class, they don't make it back into the XML.
And what makes this worse is that Microsoft sealed all of these classes so you can't derive a new class and insert your own implementation. Your only option is to move the comments outside of the AppSettings section or use XmlDocument or XDocument classes to parse the config files instead.
Sorry. This is an edge case that Microsoft just didn't plan for.
Here is a sample function that you could use to save the comments. It allows you to edit one key/value pair at a time. I've also added some stuff to format the file nicely based on the way I commonly use the files (You could easily remove that if you want). I hope this might help someone else in the future.
public static bool setConfigValue(Configuration config, string key, string val, out string errorMsg) {
try {
errorMsg = null;
string filename = config.FilePath;
//Load the config file as an XDocument
XDocument document = XDocument.Load(filename, LoadOptions.PreserveWhitespace);
if(document.Root == null) {
errorMsg = "Document was null for XDocument load.";
return false;
}
XElement appSettings = document.Root.Element("appSettings");
if(appSettings == null) {
appSettings = new XElement("appSettings");
document.Root.Add(appSettings);
}
XElement appSetting = appSettings.Elements("add").FirstOrDefault(x => x.Attribute("key").Value == key);
if (appSetting == null) {
//Create the new appSetting
appSettings.Add(new XElement("add", new XAttribute("key", key), new XAttribute("value", val)));
}
else {
//Update the current appSetting
appSetting.Attribute("value").Value = val;
}
//Format the appSetting section
XNode lastElement = null;
foreach(var elm in appSettings.DescendantNodes()) {
if(elm.NodeType == System.Xml.XmlNodeType.Text) {
if(lastElement?.NodeType == System.Xml.XmlNodeType.Element && elm.NextNode?.NodeType == System.Xml.XmlNodeType.Comment) {
//Any time the last node was an element and the next is a comment add two new lines.
((XText)elm).Value = "\n\n\t\t";
}
else {
((XText)elm).Value = "\n\t\t";
}
}
lastElement = elm;
}
//Make sure the end tag for appSettings is on a new line.
var lastNode = appSettings.DescendantNodes().Last();
if (lastNode.NodeType == System.Xml.XmlNodeType.Text) {
((XText)lastNode).Value = "\n\t";
}
else {
appSettings.Add(new XText("\n\t"));
}
//Save the changes to the config file.
document.Save(filename, SaveOptions.DisableFormatting);
return true;
}
catch (Exception ex) {
errorMsg = "There was an exception while trying to update the config value for '" + key + "' with value '" + val + "' : " + ex.ToString();
return false;
}
}
If comments are critical, it might just be that your only option is to read & save the file manually (via XmlDocument or the new Linq-related API). If however those comments are not critical, I would either let them go or maybe consider embedding them as (albeit redundant) data elements.

Categories