A call to the WCF method that accepts a list of objects. Consumption through the iPhone app

I have a WCF service that is used through an iPhone application. All other methods that accept string parameters or individual objects work fine, however, when I call a method that accepts " List<CustomObjectClass> ssf ".

I pass the NSMutableArray from CustomObjectClass this method and I get the following error:

Any ideas?

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode><faultstring xml:lang="en-AU">The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:ssf. The InnerException message was 'Error in line 2 position 6. Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. '. Please see InnerException for more details.</faultstring><detail><ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><HelpLink i:nil="true"/><InnerException><HelpLink i:nil="true"/><InnerException i:nil="true"/><Message>Error in line 2 position 6. Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. </Message><StackTrace> at ReadArrayOfScanShareFriendFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString , XmlDictionaryString , CollectionDataContract )&#xD; at System.Runtime.Serialization.CollectionDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)&#xD; at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)&#xD; at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract&amp; dataContract)&#xD; at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)&#xD; at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)&#xD; at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)&#xD; at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)&#xD; at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)</StackTrace><Type>System.Runtime.Serialization.SerializationException</Type></InnerException><Message>The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:ssf. The InnerException message was 'Error in line 2 position 6. Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. '. Please see InnerException for more details.</Message><StackTrace> at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)&#xD; at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameter(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)&#xD; at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)&#xD; at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)&#xD; at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)&#xD; at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)&#xD; at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)&#xD; at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><Type>System.ServiceModel.Dispatcher.NetDispatcherFaultException</Type></ExceptionDetail></detail></s:Fault></s:Body></s:Envelope> 
0
source share
1 answer

It looks like the SOAP message sent from the iPhone application is not in the format expected by the WCF service. In this case, you probably have to control more the serialization of NSMutableArray of CustomObjectClass es when passing the array to the method.

To check if this is a problem, you can implement and configure a WCF message inspector that will write a SOAP request message to a file, and then look at the file to see if this looks like the following SOAP message:

 <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> <s:Header> <a:Action s:mustUnderstand="1">http://tempuri.org/IService/SendData</a:Action> <a:MessageID>urn:uuid:8a582916-1b9a-47f8-8fb1-c9ff18420391</a:MessageID> <a:ReplyTo> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> </a:ReplyTo> <a:To s:mustUnderstand="1">net.tcp://localhost:13031/Service</a:To> </s:Header> <s:Body> <SendData xmlns="http://tempuri.org/"> <ssf xmlns:b="http://schemas.datacontract.org/2004/07/Common" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <!-- Zero or more CustomObjectClass elements--> <b:CustomObjectClass> <!-- Zero or more elements for CustomObjectClass properties --> </b:CustomObjectClass> </ssf> </SendData> </s:Body> </s:Envelope> 

Implement WCF Message Inspector:

  • Implement the WCF Message Inspector ( IDispatchMessageInspector ).
  • Implement endpoint behavior ( IEndpointBehavior ).
  • Implement a custom behavior extension element ( BehaviorExtensionElement ).

WCF Message Inspector :

 public class FileOutputMessageInspector : IDispatchMessageInspector { public object AfterReceiveRequest( ref Message request, IClientChannel channel, InstanceContext instanceContext ) { string path = Path.Combine( AppDomain.CurrentDomain.SetupInformation.ApplicationBase, Guid.NewGuid().ToString() + ".xml" ); File.WriteAllText( path, request.ToString() ); return null; } public void BeforeSendReply( ref Message reply, object correlationState ) { } } 

endpoint behavior :

 public class FileOutputBehavior : IEndpointBehavior { public void AddBindingParameters( ServiceEndpoint endpoint, BindingParameterCollection bindingParameters ) { } public void ApplyClientBehavior( ServiceEndpoint endpoint, ClientRuntime clientRuntime ) { throw new ApplicationException( "Behavior is not supported on client side." ); } public void ApplyDispatchBehavior( ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher ) { FileOutputMessageInspector inspector = new FileOutputMessageInspector(); endpointDispatcher.DispatchRuntime.MessageInspectors.Add( inspector ); } public void Validate( ServiceEndpoint endpoint ) { } } 

Extension element behavior:

 public class FileOutputElement : BehaviorExtensionElement { public override Type BehaviorType { get { return typeof( FileOutputBehavior ); } } protected override object CreateBehavior() { return new FileOutputBehavior(); } } 

Configure WCF Message Manager:

  • Declaring a new behavior extension (make sure the type attribute uses the correct fully qualified type name).
  • Use declared behavior extension in endpoint behavior.
  • Link to endpoint behavior.

Use the following configuration as a reference:

 <system.serviceModel> <services> <service name="Server.Service"> <endpoint address="" binding="netTcpBinding" bindingConfiguration="TCP" contract="Common.IService" behaviorConfiguration="RequestMessageToFile"/> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:13031/Service"/> </baseAddresses> </host> </service> </services> <bindings> <netTcpBinding> <binding name="TCP"> <security mode="None"/> </binding> </netTcpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="RequestMessageToFile"> <requestFileOutput /> </behavior> </endpointBehaviors> </behaviors> <extensions> <behaviorExtensions> <add name="requestFileOutput" type="Common.FileOutputElement, Common"/> </behaviorExtensions> </extensions> </system.serviceModel> 
+2
source

Source: https://habr.com/ru/post/893616/


All Articles