2013-08-21 8 views
6

オブジェクトのリストを逆シリアル化するのに問題があります。オブジェクトにシリアル化するオブジェクトを1つだけ取得できますが、リストを取得できません。私は空リストを返すだけのエラーはありません。デシリアライズの問題オブジェクトリスト

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

これは私が持っているクラスであると私はGetAll方法でデシリアライズしています::このお試しください

[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; 
    } 
} 
+0

としてリスト項目を作成することでしたエラーが出ていますか? –

+0

シリアル化されていないリストはありますか? 'GetAll()'メソッドの場合は、シリアライザがクラスメソッドを呼び出すビジネスでは(まれに、まれにしかないと思われる)ためではありません。彼らは、オブジェクトのプロパティ値を保持するビジネスを行っています。 – 48klocs

+0

エラーは表示されません。空のリストを返すだけです。私はGetAllメソッドをシリアライズしようとしていない、私はすべてのメソッドを使用してWebServiceから逆シリアル化し、その建物のオブジェクトを埋めるために使用しています。 –

答えて

6

:これは、返されるXMLでシリアル化解除後

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

を全体のBuildingListオブジェクト

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

FYI、 'XmlAttribute'で対応するプロパティを装飾することによっても可能な属性(例えば' locationtype'など)を逆シリアル化する必要がある場合。 – ricovox

+0

エラー属性 'XmlElement'はこの宣言型では無効です。これは 'property、indexer、field、param、return'宣言でのみ有効です。 –

+0

私は問題があると思う。私は私の答えを更新します。 – ricovox

2

あなたのxmlにある場所に建物がどのように対応しているのかわかりませんが、私には同等の名前が付けられていると分かります。代わりに、リストを使用してのLocationListを使用し、それは次のようになります。

[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; }  
} 

次のようにして、その後、デシリアライズすることができます:私はこれが古い(ER)の問題である知っている

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; 
+0

ビルドはLocationTypeの1つのタイプに過ぎず、この特定のアプリケーションはビルディングを必要とするだけなので、Webサービスを介して読み込まれるアプリケーションを使用しているビルディングオブジェクトを持っています。コレクション内でメソッドを返すか、またはオブジェクト内の静的メソッドでオブジェクト内にローカライズされたものすべてを保持してから、別のクラスを作成するのをやめようとしていました。 –

+1

IMHO、内部的にWebサービスを呼び出すDTOは私にとって本当に悪い考えです。また、LocationCollectionを内部に保持したまま、LocationBuildings.Locations(Location [])を返すことができます – DavidN

+0

これは私が投稿したものとどう違うのですか?リストから配列に切り替えただけで、OPがリストを要求しました ricovox

3

を、私はこれで苦労今日、カプセル化を必要としない答えが見つかりました。

仮定1:あなたはソースXmlとその構築方法を制御できます。

仮定2:あなたは

  1. List<T>オブジェクトに直接XMLをシリアル化しようとしているあなたはxxxは自分のクラスの名前(または名前ですArrayOfxxxとしてXMLのルート要素に名前を付ける必要がありますXmlTypeで指定されています(2を参照)。
  2. xml要素にクラスと異なる名前を付ける場合は、クラスにXmlTypeを使用する必要があります。

NB:あなたのタイプ名(またはクラス名)は小文字で始まっている場合、あなたは大文字に最初の文字を変換する必要があります。

例1 - 例2 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; } 
} 

なし - 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; } 
} 
-1

収集プロパティの使用[XMLArray]で。

0

私は知っている、古い質問ですが、同様の問題に直面したときにそれを見つけました。@のricovoxの答えにし、OPの質問の文脈で ビルは、これは私が彼の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() 
    { 
     ... 
    } 
} 

OPのミスは何ですかルート

関連する問題