My diary of software development

Posts tagged ‘SvcUtil’

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.

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

I appended ‘Part 1’ to this post when I started it because I know good and well that I’m not going to figure this out in one post.

On my current project, I need to communicate with a web service provided by a new partner company. I do not have access to the code behind this web service (and in a perfect world, I wouldn’t need to) and after my initial conversations with them, I got the feeling that they wouldn’t be very amenable to assisting me. So, here I am with a URL to their WSDL and SvcUtil which creates duplicate class names during proxy generation. I should say also that the web service times out when I call it but that is a seperate issue that I’m tracking down with this partner.

One duplicate class is a class named UploadDetails. When I added a service reference to my Visual Studio 2008 project, it generated duplicate class names in the Reference.cs file for all +20 data classes. The specifc class that I’m working with is called UploadDetails but I could work with any of their +20 classes to try and figure this out, I simply chose the UploadDetails class.

The duplicately named classes are all generated in the same namespace when I use the ‘Add Service Reference’ in Visual Studio. I’m not speaking of XML namespaces, I’m speaking of  the C# namespaces. However when I generate the proxy by using SvcUtil from the command line, it creates one UploadDetails class in the global namespace and one UploadDetails class in the partner’s namespace (which I will refer to as the Bubba namespace) so there are no name collision problems. Since I have more control over the options in the SvcUtil command line, I am going to use it to figure this out.

Here are the class diagrams of the 2 UploadDetails classes. One class was generated in the default namespace and one class in the Bubba namespace:

UploadDetails Class Diagrams

 Therer are several things to note about the similarities and differences in these 2 classes:

  1. The Bubba.UploadDetails class implements IExtensibleDataObject and the other class does not.
  2. The Fields and Properties of the 2 classes are the same except for the ones used to implement IExtensibleDataObject.
  3. The Delete, Insert, and Update properties are of different data types in the 2 classes.
    1. The global namespace UploadDetails class properties are an object array.
    2. The Bubba.UploadDetails class properties are of types which inherit from List<object>. These types are classes named Delete, Insert, and Update and are shown at the bottom of the above image.

In my next post I’m going to see what the XML SOAP body looks like when I use each of these 2 UploadDetails classes. I think they’ll both serialize to the same XML but I want to see for myself.