2011-04-24 9 views
6

Tengo problemas para deserializar el resultado de mi servicio web WCF. El método devuelve un List<RecipeEntity>, que se serializa a XML como se muestra a continuación. Cuando intento deserializar, obtengo una excepción, que se muestra a continuación. Parece que no puedo deserializar <ArrayOfRecipe> a List<RecipeEntity>. Tenga en cuenta que RecipeEntity se asigna por nombre de contrato al Recipe.Deserializar <ArrayOf> en XML en la lista <>

Después de buscar, veo que muchos proponen los atributos XmlArray y XmlElement, pero por lo que yo sé, no se aplican aquí en el método GetRecipes(). Solo los he visto usar en campos de clases serializadas.

Sé que podría ajustar el List<RecipeEntity> en una clase RecipeList y devolverlo en su lugar, pero preferiría deserializar directamente a la lista <> para cualquier tipo dado.

Excepción:

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: 

contrato de datos:

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

Implementación:

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

resultado Ejemplo XML, a modo de ilustración.

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

código Deserialización:

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

Respuesta

8

está usando el DataContractSerializer para serializar y deserializar XmlSerializer a. Esos dos no usan el mismo enfoque. Debe usar DataContractSerializer en su método de deserialización o debe marcar su operación o servicio con el atributo XmlSerializerFormat (en tal caso, WCF utilizará XmlSerializer en lugar de DataContractSerializer). Los atributos DataContract y DataMember son solo para DataContractSerializer. XmlSerializer usa sus propios atributos definidos en el espacio de nombre System.Xml.Serialization.

2

Simplemente primero obtiene la secuencia de respuesta y luego utiliza el DataContractSerealizer para deserealizarlo.

código DeSerealization:

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

Cuestiones relacionadas