views:

797

answers:

5

I have the following xml snippet:

<Configuration>
    <Config name="SendToAddresses"></Config>
    <Config name="CCToAddresses"></Config>
    <Config name="BCCAddresses"></Config>
</Configuration>

What I would like is to deSerialize to a strongly typed class, with all items of config in an array containing value pair (name|value).

Thanks

A: 

In order to get strong types you have to create XML schema - an XSD file that will contain definition and type of each xml node. Check out MSDN documentation about this.

Sorantis
Thanks, but thats not what I mean. What I want to do is deSerialize to a C# Class, but instead of just having a collection of Config, I somehow need to get the name attribute too for the element.
JL
Perhaps this might help http://stackoverflow.com/questions/1081325/c-how-to-xml-deserialize-object-itselfBut again, if you want to do it correctly - use schemas.
Sorantis
+3  A: 
class Program
{
    static void Main(string[] args)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Configuration));
        var xml = 
@"<Configuration>
    <Config name=""SendToAddresses"">some value</Config>
    <Config name=""CCToAddresses""></Config>
    <Config name=""BCCAddresses""></Config>
  </Configuration>";
        using (var reader = new StringReader(xml))
        {
            var configuration = (Configuration)serializer.Deserialize(reader);
        }
    }
}

public class Configuration
{
    [XmlElement(ElementName="Config")]
    public Config[] Configs { get; set; }

}

public class Config
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlText]
    public string Value { get; set; }
}
Darin Dimitrov
A: 

Is this what your looking for:

    [XmlRoot("Configuration")]
    public class Configuration
    {
        [XmlElement("Config")]
        public List<Config> Configs { get; set; }
    }

    public class Config
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        [XmlText]
        public string Value { get; set; }

        public Config() { }
    }

    // ...

    XmlSerializer s = new XmlSerializer(typeof(Configuration));
    Configuration conf = (Configuration)s.Deserialize(new StringReader("INSERTXMLHERE"));

    foreach (var config in conf.Configs)
    {
        Console.WriteLine("{0} = {1}", config.Name, config.Value);
    }
bruno conde
A: 

There is no point to deserialize an xml file into a strongly typed object to have an array of configuration.

If you can afford to alter your xml file to:

<Configuration>
  <SendToAddresses></SendToAddresses>
  <CCToAddresses></CCToAddresses>
  <BCCAddresses></BCCAddresses>
</Configuration>

And follow the simple steps below:

  1. First, you need a container (an object) to deserialize your object into.
  2. Use XSD.exe too generate the files for you (XSD schema and then CS file from XSD schema).

Use XSD.exe and you will be set within 15 minutes and have a nice strongly typed Configuration object.

Maxime
A: 

I think that that the problem you're attempting to solve has already been solved in the System.Configuration namespace?

I think this article on Code Project by Jon Rista gives a great overview how to use the Configuration classes and should help you accomplish what you're looking for.

If that's not exactly what you need you may want to consider making a serialization assembly for your project which will allow you to create assembly that contains your config class.

I ran into problems with deserialization and serialization whenever I did not create the deserializer and serializer classes during compilation. You will find over time what happens is the XmlSerialization classes that are created during runtime aren't always created or available and you'll encounter errors.

The easiest way do this is to create a new Assembly project and add a Serializeable() class with a public read/write property. Then you can use sgen to create a serializer assembly in the Post Build event like so...

sgen /a:$(TargetFileName) /force /verbose

Then you'll need to reference your Serializable assembly in whatever Assembly you'd like to perform the serialization in. As long as the AssemblyName.Serializable.Serializers are available in your bin or probing path then the dynamic assemblies won't be created at runtime and you won't encounter errors.

Once that's done you'll be able to serialize and deserialize the types that are contained within your serialization assembly.

Serializing....

IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForAssembly();
using (IsolatedStorageFileStream stream = new
    IsolatedStorageFileStream(key, FileMode.Create, isolatedStorage))
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    serializer.Serialize(stream, value);
}

Deserializing

using (IsolatedStorageFile isolatedStorage = 
     IsolatedStorageFile.GetUserStoreForAssembly())
{
    using (IsolatedStorageFileStream stream = 
      new IsolatedStorageFileStream(
         key, FileMode.OpenOrCreate, FileAccess.ReadWrite, isolatedStorage))
    {
        if (stream.Length > 0)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(stream);
        }
        else
        {
            return default(T);
        }

    }
}
Wil P