migrating webclient to WCF; WCF client serializes parametername of method

Posted by Wouter on Stack Overflow See other posts from Stack Overflow or by Wouter
Published on 2010-06-01T09:40:14Z Indexed on 2010/06/01 9:43 UTC
Read the original article Hit count: 451

Filed under:
|
|

I'm struggling with migrating from webservice/webclient architecture to WCF architecture. The object are very complex, with lots of nested xsd's and different namespaces. Proxy classes are generated by adding a Web Reference to an original wsdl with 30+ webmethods and using xsd.exe for generating the missing SOAPFault objects. My pilot WCF Service consists of only 1 webmethod which matches the exact syntax of one of the original methods: 1 object as parameter, returning 1 other object as result value. I greated a WCF Interface using those proxy classes, using attributes: XMLSerializerFormat and ServiceContract on the interface, OperationContract on one method from original wsdl specifying Action, ReplyAction, all with the proper namespaces. I create incoming client messages using SoapUI; I generated a project from the original WSDL files (causing the SoapUI project to have 30+ methods) and created one new Request at the one implemented WebMethod, changed the url to my wcf webservice and send the message. Because of the specified (Reply-)Action in the OperationContractAttribute, the message is actually received and properly deserialized into an object. To get this far (40 hours of googling), a lot of frustration led me to using a custom endpoint in which the WCF 'wrapped tags' are removed, the namespaces for nested types are corrected, and the generated wsdl get's flattened (for better compatibility with other tools then MS VisualStudio).

Interface code is this:

[XmlSerializerFormat(Use = OperationFormatUse.Literal, Style = OperationFormatStyle.Document, SupportFaults = true)]
[ServiceContract(Namespace = Constants.NamespaceStufZKN)]
public interface IOntvangAsynchroon
{

    [OperationContract(Action = Constants.NamespaceStufZKN + "/zakLk01", ReplyAction = Constants.NamespaceStufZKN + "/zakLk01", Name = "zakLk01")]
    [FaultContract(typeof(Fo03Bericht), Namespace = Constants.NamespaceStuf)]
    Bv03Bericht zakLk01([XmlElement("zakLk01", Namespace = Constants.NamespaceStufZKN)] ZAKLk01 zakLk011);

When I use a Webclient in code to send a message, everything works. My problem is, when I use a WCF client. I use ChannelFactory< IOntvangAsynchroon > to send a message. But the generated xml looks different: it includes the parametername of the method! It took me a lot of time to figure this one out, but here's what happens:

Correct xml (stripped soap envelope):

<soap:Body>
<zakLk01 xmlns="http://www.egem.nl/StUF/sector/zkn/0310">
<stuurgegevens>
<berichtcode xmlns="http://www.egem.nl/StUF/StUF0301">Bv01</berichtcode>
<zender xmlns="http://www.egem.nl/StUF/StUF0301">
<applicatie>ONBEKEND</applicatie>
</zender>
</stuurgegevens>
<parameters>
</parameters>
</zakLk01>
</soap:Body>

Bad xml:

<soap:Body>
<zakLk01 xmlns="http://www.egem.nl/StUF/sector/zkn/0310">
<zakLk011>
<stuurgegevens>
<berichtcode xmlns="http://www.egem.nl/StUF/StUF0301">Bv01</berichtcode>
<zender xmlns="http://www.egem.nl/StUF/StUF0301">
<applicatie>ONBEKEND</applicatie>
</zender>
</stuurgegevens>
<parameters>
</parameters>
</zakLk011>
</zakLk01>
</soap:Body>

Notice the 'zakLk011' element? It is the name of the parameter of the method in my interface! So NOW it is zakLk011, but it when my parameter name was 'zakLk01', the xml seemed to contain some magical duplicate of the tag above, but without namespace. Of course, you can imagine me going crazy over what was happening before finding out it was the parametername!

I know have actually created a WCF Service, at which I cannot send messages using a WCF Client anymore. For clarity: The method does get invoked using the WCF Client on my webservice, but the parameter object is empty. Because I'm using a custom endpoint to log the incoming xml, I can see the message is received fine, but just with the wrong syntax!

WCF client code:

ZAKLk01 stufbericht = MessageFactory.CreateZAKLk01();
ChannelFactory<IOntvangAsynchroon> factory = new ChannelFactory<IOntvangAsynchroon>(new BasicHttpBinding(), new EndpointAddress("http://localhost:8193/Roxit/Link/zkn0310"));
factory.Endpoint.Behaviors.Add(new LinkEndpointBehavior());
IOntvangAsynchroon client = factory.CreateChannel();
client.zakLk01(stufbericht);

I am not using a generated client, i just reference the webservice like i am lot's of times.

Can anyone please help me? I can't google anything on this...

© Stack Overflow or respective owner

Related posts about wcf

Related posts about wcf-proxy