Problems deserializing List of objects

感情迁移 提交于 2020-01-02 03:35:19

问题


I am having trouble deserializing a list of objects. I can get just one object to serialize into an object but cannot get the list. I get no error it just returns an empty List. This is the XML that gets returned:

<locations>
   <location locationtype="building" locationtypeid="1">
     <id>1</id>
     <name>Building Name</name>
     <description>Description of Building</description>
   </location>
</locations>

This is the class I have and I am deserializing in the GetAll method:

[Serializable()]
[XmlRoot("location")]
public class Building
{
    private string method;

    [XmlElement("id")]
    public int LocationID { get; set; }
    [XmlElement("name")]
    public string Name { get; set; }
    [XmlElement("description")]
    public string Description { get; set; }
    [XmlElement("mubuildingid")]
    public string MUBuildingID { get; set; }

    public List<Building> GetAll()
    {
        var listBuildings = new List<Building>();
        var building = new Building();
        var request = WebRequest.Create(method) as HttpWebRequest;
        var response = request.GetResponse() as HttpWebResponse;

        var streamReader = new StreamReader(response.GetResponseStream());
        TextReader reader = streamReader;
        var serializer = new XmlSerializer(typeof(List<Building>), 
            new XmlRootAttribute() { ElementName = "locations" });
        listBuildings = (List<Building>)serializer.Deserialize(reader);

        return listBuildings;
    }
}

回答1:


Try this:

[XmlRoot("locations")]
public class BuildingList
{
    public BuildingList() {Items = new List<Building>();}
    [XmlElement("location")]
    public List<Building> Items {get;set;}
}

Then deserialize the whole BuildingList object.

var xmlSerializer = new XmlSerializer(typeof(BuildingList));
var list = (BuildingList)xmlSerializer.Deserialize(xml);



回答2:


I know this is an old(er) question, but I struggled with this today, and found an answer that doesn't require encapsulation.

Assumption 1: You have control over the source Xml and how it is constructed.

Assumption 2: You are trying to serialise the Xml directly into a List<T> object

  1. You must name the Root element in the Xml as ArrayOfxxx where xxx is the name of your class (or the name specified in XmlType (see 2.))
  2. If you wish your xml Elements to have a different name to the class, you should use XmlType on the class.

NB: If your Type name (or class name) starts with a lowercase letter, you should convert the first character to uppercase.

Example 1 - Without XmlType

class Program
{
    static void Main(string[] args)
    {
        //String containing the xml array of items.
        string xml =
@"<ArrayOfItem>
    <Item>
        <Name>John Doe</Name>
    </Item>
    <Item>
        <Name>Martha Stewart</Name>
    </Item>
</ArrayOfItem>";


        List<Item> items = null;
        using (var mem = new MemoryStream(Encoding.Default.GetBytes(xml)))
        using (var stream = new StreamReader(mem))
        {
            var ser = new XmlSerializer(typeof(List<Item>)); //Deserialising to List<Item>
            items = (List<Item>)ser.Deserialize(stream);
        }

        if (items != null)
        {
            items.ForEach(I => Console.WriteLine(I.Name));
        }
        else
            Console.WriteLine("No Items Deserialised");

    }
}

public class Item
{
    public string Name { get; set; }
}

Example 2 - With XmlType

class Program
{
    static void Main(string[] args)
    {
        //String containing the xml array of items.
        //Note the Array Name, and the Title case on stq.
        string xml =
@"<ArrayOfStq>
    <stq>
        <Name>John Doe</Name>
    </stq>
    <stq>
        <Name>Martha Stewart</Name>
    </stq>
</ArrayOfStq>";


        List<Item> items = null;
        using (var mem = new MemoryStream(Encoding.Default.GetBytes(xml)))
        using (var stream = new StreamReader(mem))
        {
            var ser = new XmlSerializer(typeof(List<Item>)); //Deserialising to List<Item>
            items = (List<Item>)ser.Deserialize(stream);
        }

        if (items != null)
        {
            items.ForEach(I => Console.WriteLine(I.Name));
        }
        else
            Console.WriteLine("No Items Deserialised");

    }
}

[XmlType("stq")]
public class Item
{
    public string Name { get; set; }
}



回答3:


Not sure how Building corresponds with the location you have in your xml, but to me it makes more sense if they're named equivalently. Instead of using a List use a LocationList, and it becomes:

[Serializable()]
[XmlRoot("locations")]
public class LocationCollection{
    [XmlElement("location")]
    public Location[] Locations {get;set;}
}

[Serializable()]
[XmlRoot("location")]
public class Location
{    
    [XmlElement("id")]
    public int LocationID { get; set; }
    [XmlAttribute("locationtype")]
    public string LocationType {get;set;}
    [XmlElement("name")]
    public string Name { get; set; }
    [XmlElement("description")]
    public string Description { get; set; }
    [XmlElement("mubuildingid")]
    public string MUBuildingID { get; set; }    
}

You can then deserialize as follows:

var request = WebRequest.Create(method) as HttpWebRequest;
var response = request.GetResponse() as HttpWebResponse;

var streamReader = new StreamReader(response.GetResponseStream());
TextReader reader = streamReader;
var serializer = new XmlSerializer(typeof(LocationCollection), 
   new XmlRootAttribute() { ElementName = "locations" });
var listBuildings = (LocationCollection)serializer.Deserialize(reader);

return listBuildings;



回答4:


I know, old question, but came across it when faced by a similar issue. Building on @ricovox's answer and in context of the OP's question, this is the model I would use to serialize his xml:

[Serializable, XmlRoot("locations")]
public class BuildingList
{
    [XmlArrayItem("location", typeof(Building))]
    public List<Building> locations { get; set; }
}

[Serializable]
public class Building
{
    public int LocationID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string MUBuildingID { get; set; }

    public List<Building> GetAll()
    {
        ...
    }
}

The OP's mistake was to create the list item as the root




回答5:


Use [XMLArray] for collection properties.



来源:https://stackoverflow.com/questions/18367168/problems-deserializing-list-of-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!