Unable to Deserialize XML in C# - Unrecgnized element 'add' - c#

I have a C# app that uses a custom section for configuration. I have that section of XML defined as a string. The string looks like this:
var xml = #"<departments>
<department id=""1"" name=""Sporting Goods"">
<products>
<product name=""Basketball"" price=""9.99"">
<add key=""Color"" value=""Orange"" />
<add key=""Brand"" value=""[BrandName]"" />
</product>
</products>
</department>
</departments>";
This XML matches the schema defined by the classes I described here. When I pass the above string to the Departments.Deserialize method, I receive an error. The error says: "Unrecognized element 'add'". The debugger jumps to this line in my Departments class.
public void ReadXml(XmlReader reader)
{
this.DeserializeElement(reader, false);
}
I assume that the error is referring to the 'add' elements in the 'product' element. However, the Product ConfigurationElement has a property named KeyValueConfigurationCollection Items. For that reason, it seems that add would work.
Why am I getting this error how do I fix my code so that the XML string shown above can be deserialized?

Update: Long story short - wrong serializer.
Most of the code works, except that particular deserialize method.
I was able to rectify original solution (here's where I found inspiration).
The section that I've corrected and it worked (don't forget IXmlSerializable from original post):
private static string sectionName = "departments";
public static Departments Deserialize(string xml)
{
XmlSerializer serializer = new XmlSerializer(typeof(Departments), new XmlRootAttribute(sectionName));
Departments departments = null;
var xdoc = XDocument.Parse(xml);
departments = (Departments)serializer.Deserialize(xdoc.CreateReader());
//var serializer = new XmlSerializer(typeof(Departments));
//using (var reader = new StringReader(xml))
//{
// departments = (Departments)(serializer.Deserialize(reader));
//}
return departments;
}
Hopefully it will help you moving on. At least works on my machine. Let me know if full code listing needed.
[Keeping original solution, plain reading of suggested problematic xml block]
Test client.
class Program
{
static void Main(string[] args)
{
string str = #"<departments>
<department id = ""1"" name = ""Sporting Goods"">
<products>
<product name=""Basketball"" price=""9.99"">
<add key = ""Color"" value = ""Orange""/>
<add key = ""Brand"" value = ""[BrandName]""/>
</product>
</products>
</department>
</departments>";
XmlDocument xmlDoc = LoadXmlsFromString(str);
string productXpath = "descendant-or-self::product";
var nodes = ExtractNodes(xmlDoc, productXpath);
foreach (XmlNode childrenNode in nodes)
{
var node = childrenNode.SelectSingleNode("descendant-or-self::*")?.OuterXml;
var obj = Product.Deserialize(node);
}
}
private static XmlNodeList ExtractNodes(XmlDocument xmlDoc, string xpath)
{
var nodes = xmlDoc.SelectNodes(xpath);
return nodes;
}
private static XmlDocument LoadXmlsFromString(string str)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(str);
return xmlDoc;
}
}
Reading product is implemented by adding [XmlElement("add")] attribute for the list of add elements (and element-object to convert into).
[Serializable, XmlRoot("add")]
public class KeyValue
{
[XmlAttribute(AttributeName = "key")]
public string Key { get; set; }
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
public static KeyValue Deserialize(string xml)
{
KeyValue keyValue = null;
var serializer = new XmlSerializer(typeof(KeyValue));
using (var reader = new StringReader(xml))
{
keyValue = (KeyValue)(serializer.Deserialize(reader));
}
return keyValue;
}
}
[Serializable, XmlRoot("product")]
public class Product
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlAttribute(AttributeName = "price")]
public decimal Price { get; set; }
[XmlElement("add")]
public List<KeyValue> KeyValueList { get; set; }
public static Product Deserialize(string xml)
{
Product product = null;
var serializer = new XmlSerializer(typeof(Product));
using (var reader = new StringReader(xml))
{
product = (Product)(serializer.Deserialize(reader));
}
return product;
}
}

In my opinion an XmlSerializer is not needed for the configurations you have to read. All the tools that System.Configuration provides you are more than enough. Here I rewrote your configuration classes (the basic structure):
public class DepartmentsConfiguration : ConfigurationSection
{
[ConfigurationProperty("departments", IsRequired = false, IsDefaultCollection = true)]
public DepartmentItemCollection Departments
{
get
{
var departments = this["departments"] as DepartmentItemCollection;
return departments;
}
set
{
this["departments"] = value;
}
}
}
[ConfigurationCollection(typeof(DepartmentItemCollection), AddItemName = "department")]
public class DepartmentItemCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new Department();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Department)element).Name;
}
}
public class Department : ConfigurationElement
{
[ConfigurationProperty("id", IsRequired = false, IsKey = true)]
public int Id
{
get
{
return (int)(this["id"]);
}
set
{
this["id"] = value;
}
}
[ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
public string Name
{
get
{
return (string)(this["name"]);
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("products", IsRequired = false, IsKey = false, IsDefaultCollection = false)]
public ProductCollection Products
{
get
{
return (ProductCollection)this["products"];
}
set
{
this["products"] = value;
}
}
}
[ConfigurationCollection(typeof(ProductCollection), AddItemName = "product")]
public class ProductCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new Product();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Product)element).Name;
}
}
public class Product : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
public string Name
{
get
{
return (string)(this["name"]);
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("price", IsRequired = false)]
public decimal Price
{
get
{
return (decimal)(this["price"]);
}
set
{
this["price"] = value;
}
}
[ConfigurationProperty("", IsRequired = false, IsKey = false, IsDefaultCollection = true)]
[ConfigurationCollection(typeof(KeyValueConfigurationCollection), AddItemName = "add")]
public KeyValueConfigurationCollection Items
{
get
{
var items = base[""] as KeyValueConfigurationCollection;
return items;
}
set
{
base[""] = value;
}
}
}
The <configSections> in App.config:
<configSections>
<section
name="departmentConfiguration"
type="Test.DepartmentsConfiguration, Test"
allowLocation="true"
allowDefinition="Everywhere"
/>
</configSections>
<departmentConfiguration>
<departments>
<department id="1" name="Sporting Goods">
<products>
<product name="Basketball" price="9.99">
<add key="Color" value="Orange" />
<add key="Brand" value="[BrandName]" />
</product>
</products>
</department>
</departments>
</departmentConfiguration>
And how to read it using the ConfigurationManager:
DepartmentsConfiguration config = (DepartmentsConfiguration) ConfigurationManager
.GetSection("departmentConfiguration");
foreach (Department department in config.Departments)
{
Console.WriteLine($"{department.Id}, {department.Name}");
foreach (Product product in department.Products)
{
Console.WriteLine($"{product.Name}, {product.Price}");
foreach (string key in product.Items.AllKeys)
{
Console.WriteLine($"{key} -> {product.Items[key].Value}");
}
}
}
I know it is not consistent with your question, take it as a personal advice.

How about using System.Xml.Linq's XDocument ?
Personal Pros:
Simple
No 3rd Party
Easy to read, for smaller files
Allows Linq Syntax
Personal Cons:
Tends towards spaghetti code in bigger files
Not the fastest solution
Example
static void Main(string[] args)
{
var xml =
#"<departments>
<department id=""1"" name=""Sporting Goods"">
<products>
<product name=""Basketball"" price=""9.99"">
<add key=""Color"" value=""Orange"" />
<add key=""Brand"" value=""[BrandName]"" />
</product>
</products>
</department>
</departments>";
var xDoc = XDocument.Load(new StringReader(xml));
var adds = xDoc.Root.Elements("department")
.Elements("products")
.Elements("product")
.Elements("add")
.Select(s => new KeyValuePair<string, string>(s.Attribute("key").ToString(), s.Attribute("value").ToString()))
.ToList();
foreach (var department in xDoc.Root.Elements("department"))
{
Console.WriteLine("department: {0}", department.Attribute("name"));
foreach (var products in department.Elements("products"))
{
foreach (var product in products.Elements("product"))
{
Console.WriteLine("product: {0}", product.Attribute("name"));
foreach (var config in product.Elements("add"))
{
Console.WriteLine("add: {0} -> {1}", config.Attribute("key"), config.Attribute("value"));
}
}
}
}

Related

.Net Xml serialization appending negative sign to 0

I am trying to serialize the object which is having properties of type double value but output xml is having the one of the parameter value as "-0".
I am using .Net framework 3.5.
Sample code:
[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
Public class Data
{
[XmlElement(Form = XmlSchemaForm.Unqualified)]
public double Lateral { get; set;}
}
public class Test
{
Public static void Main()
{
Test t=new Test();
Data data=new Data();
data.Lateral=0;
string xml = t.ToXml(data);
Console.WriteLine(xml);
}
Public string ToXml(Data data)
{
using (StringWriter stringWriter = new StringWriter())
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Data));
xmlSerializer.Serialize(stringWriter, data);
return stringWriter.ToString();
}
}
}
}
Output xml:
<?xml version="1.0" encoding="utf-16"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lateral>-0</Lateral>
</Data>
Sometimes it happens with double 0. you can try a very simple trick
public class Data
{
private double _lateral;
public double Lateral
{
get { return _lateral + 0 ; }
set { _lateral = value; }
}
//or
public double Lateral
{
get { return _lateral; }
set { _lateral = value + 0 ; }
}
}

Trying to create a child element in Xml serialization, doesn't show up

I am trying to generate the following XML, and this is also the first time that I ever serialize XML. Could anyone explain to me why my <issuer> element isn't showing up?
What is generated:
<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="02279359-0581-41c7-a66b-199523ac8eab" IssueInstant="18:07:2014 10:41:37 AM" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" />
What I need generated:
<samlp:Response ID="02279359-0581-41c7-a66b-199523ac8eab" IssueInstant="18:07:2014 10:41:37 AM" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" >
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://www.partner.com/sso</saml:Issuer>
</samlp:Response>
What I don't understand is that I marked the Issuer as an XMLElement.
Here is my code.
MySaml.cs
[Serializable]
[XmlRoot(ElementName = "Response", Namespace = "urn:oasis:names:tc:SAML:2.0:protocol", IsNullable = false)]
public class MySaml
{
[XmlAttribute("ID")]
public string ID { get; set; }
[XmlAttribute("Version")]
public const string Version = "2.0";
[XmlAttribute("IssueInstant")]
public string IssueInstant { get; set; }
[XmlAttribute("Destination")]
public const string Destination = "https://www.site.com/SC/SSO/SingleSignOn.aspx";
[XmlAttribute(Namespace = "xmlns", AttributeName = "samlp")]
public const string samlp = "urn:oasis:names:tc:SAML:2.0:protocol";
[XmlElement(Namespace = "urn:oasis:names:tc:SAML:2.0:assertion", ElementName = "Issuer", IsNullable = false)]
public readonly Issuer Issuer = new Issuer();
}
Issuer.cs
[Serializable]
public class Issuer
{
[XmlText]
public const string Text = "https://www.partner.com/sso";
[XmlAttribute(Namespace = "xmlns", AttributeName = "saml")]
public const string saml = "urn:oasis:names:tc:SAML:2.0:assertion";
}
Lastly, The methods I am trying to use to generate the SAML (and pardon the ugly string manipulation there - I am planning to bomb it)
protected void Page_Load(object sender, EventArgs e)
{
GenerateSamlAssertion();
}
private void GenerateSamlAssertion()
{
var response = new MySaml();
response.ID = Guid.NewGuid().ToString();
response.IssueInstant = DateTime.UtcNow.ToString("dd:MM:yyyy hh:mm:ss tt");
SerializeXml(response);
}
public XmlDocument SerializeXml(MySaml mySaml)
{
var xmlSerializerNameSpace = new XmlSerializerNamespaces();
xmlSerializerNameSpace.Add("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
xmlSerializerNameSpace.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
var serializer = new XmlSerializer(typeof(MySaml));
using (var writer = new StringWriter())
{
try
{
serializer.Serialize(writer, mySaml, xmlSerializerNameSpace);
var doc = new XmlDocument();
doc.LoadXml(writer.ToString().Remove(0, writer.ToString().IndexOf("\r\n") + 1));
return doc;
}
finally
{
writer.Close();
}
}
}
I know what I am missing must either be something stupid or something small.
Thanks in Advance :)
In order to be serialized, a field or property must be public, and cannot be readonly.
Here's a worked example:
void Main()
{
Serialize(new ToSerialize());
Serialize(new ToSerialize2());
}
private void Serialize(object o)
{
var serializer = new XmlSerializer(o.GetType());
var ms = new MemoryStream();
serializer.Serialize(ms, o);
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
public class ToSerialize2
{
public ToSerialize2()
{
this.Other = new Other();
}
public Other Other;
}
public class ToSerialize
{
public readonly Other Other = new Other();
}
public class Other
{
}
The output of ToSerialzie misses the "Other" XML element.
<?xml version="1.0"?>
<ToSerialize xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
ToSerialize2 includes it:
<?xml version="1.0"?>
<ToSerialize2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Other />
</ToSerialize2>

Deserialize a portion of xml into classes

So if I have 3 different files that contain extremely long and complex xml (which i've abbreviated here) but just the root element name is different (not really random but I'd rather not duplicate classes for the same xml):
File 1
<?xml version="1.0"?>
<somerootname1>
<car>
<make>honda</make>
<model>civic</model>
</car>
</somerootname1>
File 2
<?xml version="1.0"?>
<somerootname2>
<car>
<make>honda</make>
<model>civic</model>
</car>
</somerootname2>
File 3
<?xml version="1.0"?>
<somerootname3>
<car>
<make>honda</make>
<model>civic</model>
</car>
</somerootname3>
Because XmlRootAttribute has AllowMultiple=false I can't create a single class to represent the previous xml.
Duplicate 'XmlRootAttribute' attribute
[XmlRoot(ElementName="somerootname1")]
[XmlRoot(ElementName="somerootname2")]
public class Root
{
public Automobile Car { get; set; }
}
public class Automobile
{
public string Make { get; set; }
public string Model { get; set; }
}
I thought I might be able to be sneaky and grab just the element I need and deserialize it:
var xDoc = XDocument.Parse("myfile.xml");
var xCar = xDoc.Root.Descendants()
.FirstOrDefault(d => d.Name.LocalName.Equals("car"))
var serializer = new XmlSerializer(typeof(Automobile))
using (var reader = xml.CreateReader())
{
result = (Automobile)serializer.Deserialize(reader);
}
However that results in an InvalidOperationException:
There is an error in XML document (0, 0).
With an InnerException:
<car> was not expected.
It seems really hacky to either; rename the root element and then deserialize OR take the element and prefix the <?xml> tag. Any other suggestions?
You have extracted the <car> node, but you're still deserializing from the document's root node. That's why the exception suggests that it's expecting the <car> node. The following works for me:
[XmlRoot("car")]
public class Automobile
{
[XmlElement("make")]
public string Make { get; set; }
[XmlElement("model")]
public string Model { get; set; }
}
Deserialize from <car>:
var xCar = xDoc.Root.Descendants()
.FirstOrDefault(d => d.Name.LocalName.Equals("car"));
var serializer = new XmlSerializer(typeof(Automobile));
using (var reader = xCar.CreateReader())
{
var result = (Automobile)serializer.Deserialize(reader);
Console.WriteLine(result.Make);
Console.WriteLine(result.Model);
}
I did not come up with this but just tweaked it some, the original is from: Deserialize XML To Object using Dynamic
Not sure if it is exactly what you need, but it would allow you to grab the values from the xml and put them into your class. It can be adjusted for arrays or collections as well, if there were multiple cars in one xml doc.
You will need to add:
using System.Dynamic;
using System.Xml.Linq;
protected Car ParseXml(Car NewCar) {
string xml = "<?xml version=\"1.0\"?><somerootname1> <car> <make>honda</make> <model>civic</model> </car></somerootname1>";
dynamic car = DynamicXml.Parse(xml);
NewCar.Make = car.car.make;
NewCar.Model = car.car.model;
return NewCar;
}
[Serializable]
public partial class Car
{
public Car() { }
public string Make { get; set; }
public string Model { get; set; }
}
public class DynamicXml : DynamicObject
{
XElement _root;
private DynamicXml(XElement root)
{
_root = root;
}
public static DynamicXml Parse(string xmlString)
{
return new DynamicXml(XDocument.Parse(xmlString).Root);
}
public static DynamicXml Load(string filename)
{
return new DynamicXml(XDocument.Load(filename).Root);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
var att = _root.Attribute(binder.Name);
if (att != null)
{
result = att.Value;
return true;
}
var nodes = _root.Elements(binder.Name);
if (nodes.Count() > 1)
{
result = nodes.Select(n => new DynamicXml(n)).ToList();
return true;
}
var node = _root.Element(binder.Name);
if (node != null)
{
if (node.HasElements)
{
result = new DynamicXml(node);
}
else
{
result = node.Value;
}
return true;
}
return true;
}
}

XML Parser Error in C#

I am trying to create a function to parse an XML file like this:
<?xml version="1.0" encoding="utf-8"?>
<list name="Grocery List" author="Ian" desc="Saturday grocery list">
<item color="black" done="false">Milk</item>
<item color="black" done="false">Eggs</item>
<item color="blue" done="false">Water</item>
</list>
It parses the attributes correctly, but it fails to return the values of the list items. Here is the function and class it uses:
class List
{
public string[] listItems;
public string[] colorArray;
public string[] doneArray;
public string listName;
public string listAuthor;
public string listDesc;
public string err;
}
Reader definition:
class ListReader
{
public List doListParse(string filename)
{
List l = new List();
int arrayCount = 0;
try
{
XmlReader r = XmlReader.Create(filename);
while (r.Read())
{
if (r.NodeType == XmlNodeType.Element && r.Name == "list")
{
//Get the attributes of the list
l.listName = r.GetAttribute("name");
l.listAuthor = r.GetAttribute("author");
l.listDesc = r.GetAttribute("desc");
while (r.NodeType != XmlNodeType.EndElement)
{
r.Read();
if (r.Name == "item")
{
r.Read();
if (r.NodeType == XmlNodeType.Text)
{
//Get The Attributes
l.colorArray[arrayCount] = r.GetAttribute("color");
l.doneArray[arrayCount] = r.GetAttribute("done");
//Get The Content
l.listItems[arrayCount] = r.Value.ToString();
arrayCount++;
}
r.Read();
}
}
}
}
}
catch (Exception e)
{
l.err = e.ToString();
}
return l;
}
}
When I execute the program, it gives this exception:
System.NullReferenceException: Object reference not set to an instance of an object.
What is going on here?
I'd recommend you using a serializer. The XmlSerializer class is pretty decent. It will simplify your code.
So start by defining the models that will map to this XML structure:
[XmlRoot("list")]
public class GroceryList
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("author")]
public string Author { get; set; }
[XmlAttribute("desc")]
public string Description { get; set; }
[XmlElement("item")]
public Item[] Items { get; set; }
}
public class Item
{
[XmlAttribute("color")]
public string Color { get; set; }
[XmlAttribute("done")]
public bool Done { get; set; }
[XmlText]
public string Value { get; set; }
}
and then simply deserialize the XML:
class Program
{
static void Main()
{
var serializer = new XmlSerializer(typeof(GroceryList));
using (var reader = XmlReader.Create("groceriesList.xml"))
{
var list = (GroceryList)serializer.Deserialize(reader);
// you could access the list items here
}
}
}
You can use Linq To Xml.
var xElem = XDocument.Parse(xml).Element("list"); //or XDocument.Load(filename)
var list = new
{
Name = xElem.Attribute("name").Value,
Author = xElem.Attribute("author").Value,
Desc = xElem.Attribute("desc").Value,
Items = xElem.Elements("item")
.Select(e => new{
Color = e.Attribute("color").Value,
Done = (bool)e.Attribute("done"),
Value = e.Value,
})
.ToList()
};

custom config xml setting and storing into dictionary object

I plan to set up configuration keys for FormFields, QueryString parameters etc. In my web.config I have setting as follows:
<WhiteListPaametersGroup>
<WhiteListPaameters>
<FormField1>EVENTVALIDATION</FormField1>
<FormField2>VIEWSTATE</FormField2>
<FormField3>Button1</FormField3>
<QueryString1>firstname</QueryString1>
<QueryString2>lastname</QueryString2>
</WhiteListPaameters>
</WhiteListPaametersGroup>
Then in my code, I read the value as follows:
Dictionary<string, string> parameters = new Dictionary<string,string>();
foreach (XmlNode n in section.ChildNodes)
{
parameters.Add(n.Name, n.InnerText);
}
Is there a better way of storing this. Later on, I want to be able to go through dictionary like object, and be able to get settings for FormFields, Querystrings etc.
Please let me know if I could write it cleaner.
Thanks
You can use XML serialization to store your settings and restore them directly into an object. It's not perfect but very easy to set up and gives you object save/restore.
Have this class (properties must be public):
public class WhiteListParameters
{
public string FormField1 { get; set; }
public string FormField2 { get; set; }
public string FormField3 { get; set; }
public string QueryString1 { get; set; }
public string QueryString2 { get; set; }
}
To save it to XML file run this code:
WhiteListParameters parms = new WhiteListParameters
{
FormField1 = "EVENTVALIDATION",
FormField2 = "VIEWSTATE",
FormField3 = "Button1",
QueryString1 = "firstname",
QueryString2 = "lastname"
};
using(StreamWriter sw = new StreamWriter("C:\\temp\\config.xml"))
{
XmlSerializer xs = new XmlSerializer(typeof (WhiteListParameters));
xs.Serialize(sw, parms);
sw.Close();
}
To read it back into an object:
using(StreamReader sr = new StreamReader("c:\\temp\\config.xml"))
{
XmlSerializer xs = new XmlSerializer(typeof (WhiteListParameters));
WhiteListParameters parms = (WhiteListParameters) xs.Deserialize(sr);
sr.Close();
}
For reading configuration, .NET Framework has many classes in System.Configuration namespace. The most important classes are ConfigurationSection and ConfigurationElement. Derive from these classes, add properties you want and decorate them with ConfigurationProperty attribute. Advantage of this approach is type-safety, possibility to define list of valid and the fact, that .NET Framework framework will do all reading, parsing and checking of values from web.config for you automatically.
One option you might look into is creating a custom configuration section, which you can register in the web.config.
Here's a configuration section that I created for referencing our XSLT templates:
namespace Foo.Web.Applications.CustomConfigurationSections
{
public class XslTemplateConfiguration : ConfigurationSection
{
[ConfigurationProperty("xslTemplates")]
public XslTemplateElementCollection XslTemplates
{
get { return this["xslTemplates"] as XslTemplateElementCollection; }
}
}
public class XslTemplateElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name
{
get { return this["name"] as string; }
set { this["name"] = value; }
}
[ConfigurationProperty("path", IsRequired = true)]
public string Path
{
get { return this["path"] as string; }
set { this["path"] = value; }
}
}
public class XslTemplateElementCollection : ConfigurationElementCollection
{
public XslTemplateElement this[object key]
{
get { return base.BaseGet(key) as XslTemplateElement; }
}
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override string ElementName
{
get { return "xslTemplate"; }
}
protected override bool IsElementName(string elementName)
{
bool isName = false;
if (!String.IsNullOrEmpty(elementName))
isName = elementName.Equals("xslTemplate");
return isName;
}
protected override ConfigurationElement CreateNewElement()
{
return new XslTemplateElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((XslTemplateElement)element).Name;
}
}
}
You can register this section in the web.config as follows:
<configSections>
<section name="xslTemplateConfiguration" type="Foo.Web.Applications.CustomConfigurationSections.XslTemplateConfiguration"/>
</configSections>
And you can access the collection in your code like this:
var config = WebConfigurationManager.OpenWebConfiguration("/");
if (config.HasFile)
{
var templates = config.GetSection("xslTemplateConfiguration") as XslTemplateConfiguration;
if (templates != null)
{
var templatePath = templates.XslTemplates["PO"].Path;
}
}

Categories

Resources