5

I am trying to deserialize my packages.config file in C# but the Collection i get back is always null. Is there something special that is needed if my xml file consists of a single collection of attributes?

[Serializable()]
[System.Xml.Serialization.XmlTypeAttribute()]
public class Package
{
    [System.Xml.Serialization.XmlAttribute("id")]
    public string Id {get;set;}
    [System.Xml.Serialization.XmlAttribute("version")]
    public string Version {get;set;}
}

[Serializable()]
[System.Xml.Serialization.XmlRoot("packages")]
public class PackageCollection
{
    [System.Xml.Serialization.XmlArrayItem("package", typeof(Package))]
    public Package[] Packages {get;set;}    
}


void Main()
{
    var path = "C:\D\packages.config";
    var serializer  = new System.Xml.Serialization.XmlSerializer(typeof(PackageCollection), new System.Xml.Serialization.XmlRootAttribute("packages"));
    StreamReader reader = new StreamReader(file);
    var packages2 = (PackageCollection)serializer.Deserialize(reader);
    reader.Close();
}

where my packages.config looks like

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
  <package id="Autofac" version="3.3.1" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net45" /> 
  <package id="Microsoft.AspNet.WebApi.Tracing" version="4.0.30506" targetFramework="net45" /> 
  <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net45" /> 
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" /> 
  <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" /> 
</packages> 
KnightFox
  • 3,132
  • 4
  • 20
  • 35
  • 1
    you can use xsd.exe to ensure your code is coherent with the schema - see this example http://blogs.msdn.com/b/yojoshi/archive/2011/05/14/xml-serialization-and-deserialization-entity-classes-with-xsd-exe.aspx – Isantipov Sep 04 '14 at 22:49

2 Answers2

2

Use XmlElement in this case:

[Serializable()]
[System.Xml.Serialization.XmlRoot("packages")]
public class PackageCollection
{
    [System.Xml.Serialization.XmlElement("package", typeof(Package))]
    public Package[] Packages { get; set; }
}
Kram
  • 4,099
  • 4
  • 39
  • 60
2

This code appears to function according to your needs based on the included testing:

[Serializable()]
[System.Xml.Serialization.XmlTypeAttribute()]
public class Package
{
    [System.Xml.Serialization.XmlAttributeAttribute("id")]
    public string Id { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute("version")]
    public string Version { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute("targetFramework")]
    public string TargetFramework { get; set; }
}

[Serializable()]
[System.Xml.Serialization.XmlRoot("packages")]
public class PackageCollection
{
    [System.Xml.Serialization.XmlElementAttribute("package")]
    public Package[] Packages { get; set; }
}

class Program
{
    static void Main()
    {
        var path = @"C:\packages.config";
        var serializer = new System.Xml.Serialization.XmlSerializer(typeof(PackageCollection));
        StreamReader reader = new StreamReader(path);
        var packages2 = (PackageCollection)serializer.Deserialize(reader);
        foreach (Package pkg in packages2.Packages)
        {
            Console.WriteLine("ID: " + pkg.Id);
            Console.WriteLine("Version: " + pkg.Version);
            Console.WriteLine("Target Framework: " + pkg.TargetFramework);
            Console.WriteLine();              
        }     
        reader.Close();
        Console.ReadLine();
    }
}

As @Isantipov mentioned, XML Schema Definition Tool (Xsd.exe)- MDSN can be of assistance.

See also the question How to Deserialize XML document for some additional information, specifically Marc Gravell's answer.

Community
  • 1
  • 1
jordanhill123
  • 4,142
  • 2
  • 31
  • 40