views:

30

answers:

1

I have a client (that isn't very flexible in the SOAP it sends) which generates SOAP similar to the following from a method with signature void Test(int[] test):

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
    <SOAP:Body>
        <Test xmlns="http://www.mydomain.com/"&gt;
            <test>
                <item>1</item>
                <item>2</item>
                <item>3</item>
                <item>4</item>
                <item>5</item>
                <item>7</item>
            </test>
        </Test>
    </SOAP:Body>
</SOAP:Envelope>

I need my WCF SOAP web service to deserialize this correctly.

By default it throws the following exception:

System.ServiceModel.Dispatcher.NetDispatcherFaultException: The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'Test'. End element 'test' from namespace 'http://www.mydomain.com/' expected. Found element 'item' from namespace 'http://www.mydomain.com/'. Line 6, position 7. ---> System.Xml.XmlException: End element 'test' from namespace 'http://www.mydomain.com/' expected. Found element 'item' from namespace 'http://www.mydomain.com/'. Line 6, position 7.
   at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
   at System.Xml.XmlBaseReader.ReadEndElement()
   at System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.PartInfo.ReadValue(XmlDictionaryReader reader)
   at System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters)
   at System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(XmlDictionaryReader reader, Object[] parameters)
   at System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(Message message, Object[] parameters)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

If you add the XmlSerializerFormat attribute to the service interface then no exception is thrown but the resulting array is empty (I suspect it does not recognize the individual elements of the array properly).

If you add the XmlArrayItem attribute to the parameter it doesn't seem to change anything (void Test([XmlArrayItem("item")] int[] test); in the service).

I've tried various other combinations of XmlSerializerFormat, XmlArrayItem, and XmlArray, with no luck.

What do I need to do to get this working as expected?

A: 

Here's the answer, hope it's of use to someone:

[CollectionDataContract(ItemName = "item", Namespace = "http://www.mydomain.com/")]
public class ClientArray<T> : List<T> {

}

void Test(ClientArray<int> test);
Lawrence Johnston