将XML中的<ArrayOf>反序列化为List <>

ang*_*sen 6 .net xml wcf serialization list

我无法从WCF Web服务反序列化结果.该方法返回一个List<RecipeEntity>,序列化为XML,如下所示.当我尝试反序列化时,我得到一个异常,如下所示.看来我无法反序列化<ArrayOfRecipe>List<RecipeEntity>.请注意,RecipeEntity按合同名称映射到Recipe.

在搜索之后,我看到很多人提出了XmlArray和XmlElement属性,但据我所知,它们不适用于此GetRecipes()方法.我只看到它们用在序列化类的字段上.

我知道我可以将它包装List<RecipeEntity>在一个RecipeList类中并返回它,但我宁愿直接反序列化为任何给定类型的List <>.

例外:

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: 
Run Code Online (Sandbox Code Playgroud)

数据合同:

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

执行:

[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();
    }
}
Run Code Online (Sandbox Code Playgroud)

示例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>
Run Code Online (Sandbox Code Playgroud)

反序列化代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

Lad*_*nka 9

您正在使用DataContractSerializer序列化和XmlSerializer反序列化.这两个不使用相同的方法.您必须DataContractSerializer在反序列化方法中使用,或者必须使用XmlSerializerFormat属性标记您的操作或服务(在这种情况下,WCF将使用XmlSerializer而不是DataContractSerializer).DataContractDataMember属性仅适用于DataContractSerializer.XmlSerializer使用System.Xml.Serialization命名空间中定义的自己的属性.