本文介绍了反序列化< ArrayOf>在XML中列出<>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有麻烦反序列化从我的WCF web服务的结果。该方法返回一个名单,其中,RecipeEntity> ,这是序列化为XML,如下图所示。当我尝试反序列化我刚刚得到一个异常,如下图所示。看来我无法反序列化< ArrayOfRecipe> 名单,其中,RecipeEntity> 。需要注意的是 RecipeEntity 是由合同的名称映射到配方

搜索我看到经过多次提出XmlArray和的XmlElement属性,但据我可以告诉他们不要在 GetRecipes()方法适用于此。我只看到他们在序列化类的领域。

我知道我可以换行名单,其中,RecipeEntity> RecipeList 类,并返回代替,但我宁可直接反序列化到列表<>对于任何给定类型

例外:

  System.InvalidOperationException了抓
  消息=有一个在XML文档的错误(1,2)。
  堆栈跟踪:
       在System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader的XmlReader的,字符串的encodingStyle,对象的事件)
       在System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader的XmlReader的,字符串的encodingStyle)
       在System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader的的XmlReader)
       在GroceriesAppSL.Pages.Home.GetRecipesCallback(RestResponse响应)
  的InnerException信息:System.InvalidOperationException
       消息=< ArrayOfRecipe的xmlns =Groceries.Entities'>是没有预料到。
       堆栈跟踪:
            在Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderList1.Read5_Recipe()
       的InnerException:
 

数据合同:

  [DataContract(名称为配方,命名空间=Groceries.Entities)
公共类RecipeEntity
{
    [数据成员]公众诠释标识;
    [数据成员]公共字符串名称;
    [数据成员]公共字符串描述;
}
 

执行:

  [的ServiceContract]
公共接口IMyService
{
    [OperationContract的]
    [WebGet(ResponseFormat = WebMessageFormat.Xml,UriTemplate =食谱/ {用户名})]
    名单< RecipeEntity> GetRecipes(字符串的用户名);
}

公共类为MyService:IMyService
{
    公开名单< RecipeEntity> GetRecipes(字符串的用户名)
    {
        返回_recipeDB.Recipes.Select(ToEntity).ToList();
    }
}
 

例如XML结果,仅用于说明目的。

 < ArrayOfRecipe的xmlns =Groceries.Entities的xmlns:I =htt​​p://www.w3.org/2001/XMLSchema-instance>
<配方>
<编号> 139< / ID>
<名称>&ExampleRecipe LT; /名称>
<描述> 5升牛奶; 4个鸡蛋< /说明>
< /配方>
<配方> ...< /配方>
<配方> ...< /配方>
<配方> ...< /配方>
...
< / ArrayOfRecipe>
 

反序列化code:

 使用(VAR的XMLReader = XmlReader.Create(新StringReader(response.Content)))
{
    VAR XS =新System.Xml.Serialization.XmlSerializer(typeof运算(名单< RecipeEntity>));
    VAR食谱=(名单< RecipeEntity>)xs.Deserialize(XmlReader的);
}
 

解决方案

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

I have trouble deserializing the result from my WCF webservice. The method returns a List<RecipeEntity>, which is serialized to XML as shown below. When I try to deserialize I just get an exception, shown below. It seems I cannot deserialize <ArrayOfRecipe> to List<RecipeEntity>. Note that RecipeEntity is mapped by contract name to Recipe.

After searching I see many propose XmlArray and XmlElement attributes, but as far as I can tell they do not apply here on the GetRecipes() method. I have only seen them used on fields of serialized classes.

I know I could wrap the List<RecipeEntity> in a RecipeList class and return that instead, but I would rather deserialize directly to List<> for any given type.

Exception:

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:

Data contract:

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

Implementation:

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

Example XML result, for illustration purposes only.

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

Deserialization code:

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);
}
解决方案

You are using DataContractSerializer to serialize and XmlSerializer to deserialize. Those two doesn't use the same approach. You must either use DataContractSerializer in your deserialization method or you must mark your operation or service with XmlSerializerFormat attribute (in such case WCF will use XmlSerializer instead of DataContractSerializer). DataContract and DataMember attributes are only for DataContractSerializer. XmlSerializer uses its own attributes defined in System.Xml.Serialization namespace.

这篇关于反序列化&LT; ArrayOf&GT;在XML中列出&LT;&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 12:30