开发者

Serialization issues calling WCF service from iPhone MonoTouch app

I have a WCF service on a Windows Server and I am trying to invoke the service from an iPhone Application in MonoDevelopment. The web service client was generated using Silverlight service generation utility and copied to the iPhone development project in the MonoTouch environment.

So the service is pretty straightforward. I have a method that calls a GetCustomers() methods and returns a List<Customer>. I can create the client successfully in the MonoTouch iPhone application code. The method does execute and if I try to do a count on the result it tells me there are 91 records (Northwind database / Customers table). So I am sure that the service is working just fine.

Problem is when I try to access any property of Customer object I get the following error:

The CustomerName property does have public getter and setter

but the following exception says it does not. I need some help if someone can walk me through what I am doing wrong!

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.Serializati开发者_如何学JAVAon/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 


No, the service is not working just fine. It appears it's an async method, so when your first call appears to be successful, it may not be really unless you close the async call and get the return value. The processing and counting of the result may very well have been successful, but the actual serialization of the result -- which requires the Customer type to have both a setter and getter -- is not.

This is one of the few exceptions in WCF that is almost always right and very specific. Are you sure the Customer type has both a getter and setter? Are their access levels consistent?


The MonoTouch linker will exclude any code that isn't used from the final native iOS binaries. In your case, the getter/setter probably isn't used in your project and so isn't getting into the native version.

To fix this, you can decorate your DataMember properties with the MonoTouch.Foundation.Preserve attribute. Or, stick the Preserve attribute on the class that is your DataContract and pass in AllMembers = true, like the example below.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜