我无法从WCF Web服务反序列化结果。该方法返回List<RecipeEntity>
,它被序列化为XML,如下所示。当我尝试反序列化时,我得到一个例外,如下所示。我似乎无法将<ArrayOfRecipe>
反序列化为List<RecipeEntity>
。请注意,RecipeEntity
按合同名称映射到Recipe
。
搜索后我看到很多人提出XmlArray和XmlElement属性,但据我所知,它们不适用于GetRecipes()
方法。我只看到它们用在序列化类的字段上。
我知道我可以将List<RecipeEntity>
包装在RecipeList
类中并返回它,但我宁愿反序列化为List&lt;&gt;对于任何给定的类型。
例外:
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);
}
答案 0 :(得分:9)
您正在使用DataContractSerializer
序列化并XmlSerializer
进行反序列化。这两个不使用相同的方法。您必须在反序列化方法中使用DataContractSerializer
,或者必须使用XmlSerializerFormat
属性标记您的操作或服务(在这种情况下,WCF将使用XmlSerializer
而不是DataContractSerializer
)。 DataContract
和DataMember
属性仅适用于DataContractSerializer
。 XmlSerializer
使用System.Xml.Serialization
命名空间中定义的自己的属性。
答案 1 :(得分:2)
首先,您获得响应流,然后使用DataContractSerializer对其进行反序列化。
DeSerialization代码:
using(Stream answer=webResponse.GetResponseStream())
{
DataContractSerializer xmlSer = new DataContractSerializer(typeof(RecipeEntity[]));
var RecipeList = (RecipeEntity[])xmlSer.ReadObject(answer);
}