2013-08-21 1 views
6

개체 목록을 deserialize하는 데 문제가 있습니다. 하나의 객체 만 객체로 직렬화 할 수는 있지만 목록을 가져올 수는 없습니다. 난 그냥 빈 목록을 반환 아무런 오류가 발생합니다.deserializing 문제 개체 목록

<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()'메소드 인 경우, 클래스 메소드를 호출하는 비즈니스에서 serializer가 (아마도 드물게는) 그런 것이 아니기 때문입니다. 그들은 물건의 재산 가치를 보존하는 사업에 종사하고 있습니다. – 48klocs

+0

오류가 발생하지 않습니다. 단지 빈 목록 만 반환합니다. GetAll 메서드를 serialize하려면 노력하고있어, Get 메서드를 사용하여 webservice deserialize 및 해당 건물 개체 채우기. –

답변

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

다음과 같이 다음 역 직렬화 할 수 있습니다 :이 오래된 (어) 질문 알고

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

Building은 LocationType의 한 유형이며,이 특정 애플리케이션은 건물 만 필요로하므로 웹 서비스를 통해 채울 응용 프로그램을 사용하는 건물 객체가 있습니다. 콜렉션에 대한 또 다른 클래스를 만드는 것에서 벗어나려고 노력 중이던데, 그 이유는 콜렉션에 대한 메소드 또는 메소드 내부의 정적 메소드에서 모든 것이 객체에 로컬 화 된 상태로 유지 되었기 때문입니다. –

+1

IMHO, 내부적으로 웹 서비스를 호출하는 DTO는 나에게 정말로 나쁜 생각처럼 보입니다. 또한 LocationCollection을 내부에 보관하고 LocationBuildings.Locations (Location [])를 반환 할 수 있습니다. – DavidN

+0

내가 게시 한 것과 다른 점은 무엇입니까? 목록 을 배열로 바꿨을 뿐이며 OP가 목록을 요청했습니다 ricovox

3

을,하지만 난이 고생 오늘, 캡슐화가 필요없는 대답을 발견했습니다.

가정 1 : 당신은 소스 XML과 그것이 어떻게 구성되는지 제어 할 수 있습니다.

가정 2 : 당신은 List<T> 객체로 XML을 직접에는 직렬화하려고하는 당신은 xxx는 클래스의 이름입니다 ArrayOfxxx과 XML의 루트 요소 (또는 이름의 이름을 지정해야합니다

  1. XmlType에 지정되어 있습니다 (2 참조).
  2. xml 요소의 클래스 이름을 변경하려면 클래스에 XmlType을 사용해야합니다.

NB (또는 클래스 이름)하여 유형 이름이 소문자로 시작하는 경우, 당신은 대문자로 첫 번째 문자를 변환해야합니다.

예 1 - 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; } 
} 

예 2 없음 - 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; } 
} 
0

나는 옛날 질문이지만, 비슷한 문제에 직면했을 때 우연히 만났습니다. 건물에 @ ricovox의 대답과 영업 이익의 질문의 맥락에서, 이것은 내가 자신의 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() 
    { 
     ... 
    } 
} 
은 무엇

영업의 실수가 루트로 목록 항목을 만드는 것이었다됩니다