序列化问题从iPhone MonoTouch应用程序调用WCF服务

时间:2011-02-14 00:04:13

标签: iphone wcf

我在Windows Server上有一个WCF服务,我试图从MonoDevelopment中的iPhone应用程序调用该服务。 Web服务客户端是使用Silverlight服务生成实用程序生成的,并复制到MonoTouch环境中的iPhone开发项目。

所以服务非常简单。我有一个方法调用GetCustomers()方法并返回List<Customer>。我可以在MonoTouch iPhone应用程序代码中成功创建客户端。该方法确实执行,如果我尝试对结果进行计数,它告诉我有91条记录(Northwind数据库/ Customers表)。所以我确信该服务工作得很好。

问题是当我尝试访问Customer对象的任何属性时,我收到以下错误:

  

CustomerName属性确实有公共getter和setter

但是以下异常表明它没有。如果有人可以告诉我我做错了什么,我需要一些帮助!

Exception in async operation: System.Runtime.Serialization.InvalidDataContractException: DataMember property 'System.String CustomerName' on type 'NorthwindService.Customer' must have both getter and setter.
  at System.Runtime.Serialization.SharedContractMap.GetMembers (System.Type type, System.Xml.XmlQualifiedName qname, Boolean declared_only) [0x00116] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs:553 
  at System.Runtime.Serialization.SharedContractMap.Initialize () [0x00053] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs:516 
  at System.Runtime.Serialization.KnownTypeCollection.RegisterContract (System.Type type) [0x0004f] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:766 
  at System.Runtime.Serialization.KnownTypeCollection.TryRegister (System.Type type) [0x0002a] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:593 
  at System.Runtime.Serialization.KnownTypeCollection.RegisterCollection (System.Type type) [0x0000f] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:666 
  at System.Runtime.Serialization.KnownTypeCollection.TryRegister (System.Type type) [0x00062] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:605 
  at System.Runtime.Serialization.KnownTypeCollection.InsertItem (Int32 index, System.Type type) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs:389 
  at System.Collections.ObjectModel.Collection`1[T].Add (.T item) [0x0000c] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs:72 
  at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlDictionaryReader reader, Boolean verifyObjectName) [0x0000c] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs:267 
  at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlObjectSerializer.cs:74 
  at System.ServiceModel.Dispatcher.DataContractMessagesFormatter.MessageToParts (System.ServiceModel.Description.MessageDescription md, System.ServiceModel.Channels.Message message) [0x000b8] in /Developer/MonoTouch/Source/mono/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs:364 
  at System.ServiceModel.Dispatcher.BaseMessagesFormatter.DeserializeReply (System.ServiceModel.Channels.Message message, System.Object[] parameters) [0x00043] in /Developer/MonoTouch/Source/mono/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs:175 
  at System.ServiceModel.ClientRuntimeChannel.Request (System.ServiceModel.Description.OperationDescription od, System.Object[] parameters) [0x0016a] in /Developer/MonoTouch/Source/mono/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:500 
  at System.ServiceModel.ClientRuntimeChannel.DoProcess (System.Reflection.MethodBase method, System.String operationName, System.Object[] parameters) [0x00038] in /Developer/MonoTouch/Source/mono/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:443 
  at System.ServiceModel.ClientRuntimeChannel.Process (System.Reflection.MethodBase method, System.String operationName, System.Object[] parameters) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs:425 

2 个答案:

答案 0 :(得分:0)

不,服务工作不正常。它似乎是一个异步方法,所以当你的第一个调用似乎成功时,它可能不是真的,除非你关闭异步调用并获得返回值。结果的处理和计数很可能已经成功,但结果的实际序列化 - 需要Customer类型同时具有setter和getter - 不是。

这是WCF中少数几个总是正确且非常具体的例外之一。您确定Customer类型同时具有getter和setter吗?他们的访问级别是否一致?

答案 1 :(得分:0)

MonoTouch链接器将排除最终本机iOS二进制文件中未使用的任何代码。在您的情况下,getter / setter可能未在您的项目中使用,因此不会进入本机版本。

要解决此问题,您可以使用MonoTouch.Foundation.Preserve属性修饰DataMember属性。或者,将Preserve属性粘贴到您的DataContract类并传入AllMembers = true,如下例所示。

[DataContract,
MonoTouch.Foundation.Preserve(AllMembers=true)]
public class EntityClass
{
    [DataMember]
    public string Field {get;set;}
}