【问题标题】:Deserialize <ArrayOf> in XML to List<>将 XML 中的 <ArrayOf> 反序列化为 List<>
【发布时间】:2011-08-12 00:18:19
【问题描述】:

我在反序列化 WCF Web 服务的结果时遇到了问题。该方法返回一个List&lt;RecipeEntity&gt;,它被序列化为XML,如下所示。当我尝试反序列化时,我得到一个异常,如下所示。看来我无法将&lt;ArrayOfRecipe&gt; 反序列化为List&lt;RecipeEntity&gt;。请注意,RecipeEntity 按合约名称映射到 Recipe

搜索后,我看到许多提议 XmlArray 和 XmlElement 属性,但据我所知,它们不适用于 GetRecipes() 方法。我只看到它们用于序列化类的字段。

我知道我可以将 List&lt;RecipeEntity&gt; 包装在 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: 

数据合约:

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

【问题讨论】:

    标签: .net xml wcf list serialization


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      只需首先获取响应流,然后使用 DataContractSerealizer 去实现它。

      DeSerealization 代码:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-28
        • 2021-11-12
        • 2018-10-30
        • 1970-01-01
        • 2012-08-29
        • 2012-04-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多