My diary of software development

Archive for February, 2010

Why SvcUtil creates duplicate named classes when generating the proxy – Part 2

Part 1 of this post is here.

I wanted to see what the SOAP body looked like between these two UploadDetails classes. SvcUtil generated one UploadDetails class in the global namespace and the other class in a namespace which I called ‘Bubba’ and both had to be serialized to XML for the SOAP body, depending on which one I used in the generated proxy client call. I was able to get the generated SOAP body of the message by using Fiddler. The global namespace UploadDetails XML is shown below with lines 15-52 removed:

Global Namespace UploadDetails

The Bubba namespace UploadDetails XML is shown below with lines 14-41 removed:

Bubba Namespace UploadDetails

So how was it that I was able to choose which UploadDetails class I wanted to send? To explain that, I’ll explain the steps I went through at the beginning of this odyssey.

When I used Visual Studio’s ‘Add Service Reference’ to generate a proxy for this partner’s WSDL, the generated proxy put both UploadDetails classes in the global namespace. This resulted in a name collision compile time error so I decided to use the command line SvcUtil which did seperate the UploadDetails classes between 2 namespaces. One UploadDetails class was placed in the global namespace and the other in our partner’s namespace which I’ll refer to as Partner.A.B.C.D. SvcUtil generated the proxy client to accept the global namespace UploadDetails which left the Partner.A.B.C.D.UploadDetails class just hanging around with nothing referencing it. But I found out that if I ran SvcUtil with the /namespace option and told it to assign the classes in the partner’s namespace Partner.A.B.C.D to a namespace I called ‘Bubba’, then the SvcUtil generated the proxy client to accept the Bubba namespace UploadDetails. And that is how I was able to run the proxy client with both namespace UploadDetails classes to see how they were serialized to XML. Below is a screen show which summarizes the important points of this. It shows the class diagrams for each UploadDetails and the key differences in the serialized XML for both classes:

Serialization Differences

So basically, an object[] array is serialized into <data> elements and a List<object> is serialized into <anyType> elements. Which is strange because I thought it’d be the other way around but I double checked it and those are the correct elements. I know that WCF uses the DataContractXMLSerializer by default. I could have used the /serializer parameter to SvcUtil to have it use the XmlSerializer which would have given me more control over how exactly the object was serialized to XML but I stopped at this point.

In my first post I indicated that I was getting a timeout error when calling this partner’s web service. Lo and behold, the partner sent me an updated WSDL which fixed that problem. Apparently their first WSDL was in error.

After getting the new WSDL and being able to successfully call the web service, I checked to see which set of XML would be accepted and found that they wanted the XML generated from the global namespace UploadDetails. I got an exception when I sent the other UploadDetails. Since at this point, I could call the partner’s web service and since I had many more things to work on, I chose to stop pursuing why SvcUtil generated two classes.

In summary, SvcUtil generated 2 classes with the same name: UploadDetails. I was able to direct the namespace each class was generated into by using the /namespace parameter which also drove which class the generated proxy client would accept. I fed both namespace classes into the web service call to see which one the web service would accept and found that it accepted the global namespace UploadDetails. Their web service did not accept the XML generated from serializing the Bubba (or the Partner.A.B.C.D) namespace UploadDetails.