2011-04-24 6 views
6

내 WCF 웹 서비스에서 결과를 역 직렬화하는 데 어려움이 있습니다. 이 메서드는 List<RecipeEntity>을 반환하며, 아래 그림과 같이 XML로 serialize됩니다. deserialize하려고 할 때 나는 예외를 얻는다. 그것은 을 List<RecipeEntity>으로 비 직렬화 할 수없는 것 같습니다. RecipeEntity은 계약 이름별로 Recipe에 매핑됩니다.<ArrayOf>을 XML로 역 직렬화 목록 <>

검색 후 많은 사람들이 XmlArray 및 XmlElement 특성을 제안하지만 여기까지는 GetRecipes() 메서드에 적용되지 않는다고 말할 수 있습니다. 나는 그들이 직렬화 된 클래스의 필드에서만 사용되는 것을 보았다.

List<RecipeEntity>RecipeList 클래스로 랩핑하고 대신 반환 할 수 있지만 특정 유형의 경우 <>에 직접 deserialize합니다.

예외 :

System.InvalidOperationException was caught 
    Message=There is an error in XML document (1, 2). 
    StackTrace: 
     at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, Object events) 
     at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) 
     at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader) 
     at GroceriesAppSL.Pages.Home.GetRecipesCallback(RestResponse response) 
    InnerException: System.InvalidOperationException 
     Message=<ArrayOfRecipe xmlns='Groceries.Entities'> was not expected. 
     StackTrace: 
      at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderList1.Read5_Recipe() 
     InnerException: 

데이터 계약 :

[DataContract(Name = "Recipe", Namespace = "Groceries.Entities")] 
public class RecipeEntity 
{ 
    [DataMember] public int Id; 
    [DataMember] public string Name; 
    [DataMember] public string Description; 
} 

구현 :

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    [WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = "Recipes/{username}")] 
    List<RecipeEntity> GetRecipes(string username); 
} 

public class MyService : IMyService 
{ 
    public List<RecipeEntity> GetRecipes(string username) 
    { 
     return _recipeDB.Recipes.Select(ToEntity).ToList(); 
    } 
} 

예 XML 결과, 그림의 목적으로 만.

<ArrayOfRecipe xmlns="Groceries.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
<Recipe> 
<Id>139</Id> 
<Name>ExampleRecipe</Name> 
<Description>5 L milk;4 eggs</Description> 
</Recipe> 
<Recipe>...</Recipe> 
<Recipe>...</Recipe> 
<Recipe>...</Recipe> 
... 
</ArrayOfRecipe> 

역 직렬화 코드 :

using (var xmlReader = XmlReader.Create(new StringReader(response.Content))) 
{ 
    var xs = new System.Xml.Serialization.XmlSerializer(typeof(List<RecipeEntity>)); 
    var recipes = (List<RecipeEntity>)xs.Deserialize(xmlReader); 
} 

답변

8
당신은 직렬화 DataContractSerializer를 사용

XmlSerializer는 역 직렬화합니다. 두 사람은 같은 접근법을 사용하지 않습니다. deserialization 메서드에서 DataContractSerializer을 사용하거나 XmlSerializerFormat 특성으로 작업 또는 서비스를 표시해야합니다 (이 경우 WCF는 DataContractSerializer 대신 XmlSerializer을 사용합니다). DataContractDataMember 속성은 DataContractSerializer에만 해당됩니다. XmlSerializerSystem.Xml.Serialization 네임 스페이스에 정의 된 자체 특성을 사용합니다.

2

먼저 응답 스트림을 얻은 다음 DataContractSerealizer를 사용하여이를 deserealize하십시오.

DeSerealization 코드 :

using(Stream answer=webResponse.GetResponseStream()) 
    { 
    DataContractSerializer xmlSer = new DataContractSerializer(typeof(RecipeEntity[])); 
    var RecipeList = (RecipeEntity[])xmlSer.ReadObject(answer); 
    }